spritekit冲突检测不一致(无法获取两个节点的位置)

时间:2015-11-18 18:34:07

标签: swift sprite-kit collision-detection

在didBeginContact函数中,我成功捕获了水平网格线和圆之间的碰撞。

碰撞时,我可以成功获得圆圈(头部)的位置。

    if let headBody = contact.bodyB.node as? SnakeBodyUnit {
        print("head position ", headBody.position)
    }

这成功打印出来: 头位(87.536979675293,267.116882324219)

现在,如果我尝试检查水平线:

    if let tripRow = contact.bodyA.node as? HeadTripper {
        print("row position ", tripRow.position)
    }

我收到以下错误: po tripRow 错误:: 1:1:错误:使用未解析的标识符' tripRow' tripRow

以下是此检测触发的条件:

if (contact.bodyA.categoryBitMask == ColliderType.TripRow && contact.bodyB.categoryBitMask == ColliderType.Head) {
//contact successfully fires
}

HeadTripper类和SnakeBodyUnit类都是SKNode类。

这是SnakeBodyUnit类:

import SpriteKit

class SnakeBodyUnit : SKNode {

    var bodyDir: Direction?
    var id = -1
    var staticIDref = -1
    var partX:CGFloat = -1
    var partY:CGFloat = -1
    var bodyT = -1
    var staticTurn: TurnCrumb?
    var turnRequested = 0
    var requestedTurn: Direction?

    var unitHolder: SKSpriteNode?

    init(size: CGSize, bodyType: Int) {
        super.init()

        bodyT = bodyType

        let reducedSize = size.width

        unitHolder = SKSpriteNode()

        unitHolder!.size = CGSize(width: (size.width), height: (size.height))

        if (bodyT == 0) {
            //head

            unitHolder!.color = UIColor.clearColor()
            //unitHolder!.position = CGPoint(x:xPos, y:yPos);

            let shape = SKShapeNode(circleOfRadius: reducedSize/2)
            shape.fillColor = UIColor.whiteColor()
            shape.strokeColor = UIColor.whiteColor()
            shape.position = CGPoint(x: reducedSize/2, y: reducedSize/2)
            unitHolder!.addChild(shape)

            self.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(reducedSize, reducedSize), center: CGPointMake(reducedSize/2, reducedSize/2))
            self.physicsBody?.affectedByGravity = false
            self.physicsBody?.categoryBitMask = ColliderType.Head
            self.physicsBody?.dynamic = false
            self.physicsBody?.contactTestBitMask = ColliderType.TripRow | ColliderType.TripColumn | ColliderType.Food | ColliderType.Body | ColliderType.WallLeft | ColliderType.WallRight | ColliderType.WallBottom | ColliderType.WallTop | ColliderType.Canvas

        } else if (bodyT == 1) {
            //body part
            self.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(reducedSize, reducedSize), center: CGPointMake(reducedSize/2, reducedSize/2))
            self.physicsBody?.affectedByGravity = false
            self.physicsBody?.categoryBitMask = ColliderType.Body
            self.physicsBody!.collisionBitMask = 0
            self.physicsBody?.dynamic = true
            self.physicsBody?.contactTestBitMask = ColliderType.WallLeft | ColliderType.WallRight | ColliderType.WallBottom | ColliderType.WallTop | ColliderType.BodyStatic


        } else if (bodyT == 2) {
            //static corner
            self.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(reducedSize/2, reducedSize/2), center: CGPointMake(reducedSize/2, reducedSize/2))
            self.physicsBody?.affectedByGravity = false
            self.physicsBody?.categoryBitMask = ColliderType.BodyStatic
            self.physicsBody!.collisionBitMask = 0
            self.physicsBody?.dynamic = true
        }

        unitHolder!.anchorPoint = CGPoint(x: 0, y: 0)
        self.addChild(unitHolder!)

    }
    func updateColor(color: UIColor) {
        unitHolder!.color = color
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        //fatalError("init coder not implemented")
    }
}

这是HeadTripper类:

import SpriteKit

class HeadTripper : SKNode {

    var id = -1
    var rowTripLine: SKSpriteNode?
    var colTripLine: SKSpriteNode?


    init(size: CGSize, rowOrCol: Int) {
    //init(size: CGSize, xPos: Double, yPos: Double, rowOrCol: Int) {
        super.init()
        //row 0
        //col 1

        if (rowOrCol == 0) {
            //row
            rowTripLine = SKSpriteNode()
            rowTripLine!.color = UIColor.redColor()

            //rowTripLine!.position = CGPoint(x: 0, y: yPos);
            rowTripLine!.size = CGSize(width: Int(size.width), height: 1)

            //borderLeft!.physicsBody = SKPhysicsBody(rectangleOfSize: size, center: CGPointMake(reducedSize/2, reducedSize/2))
            rowTripLine!.physicsBody = SKPhysicsBody(rectangleOfSize: rowTripLine!.size, center: CGPointMake(rowTripLine!.size.width/2, rowTripLine!.size.height/2))
            rowTripLine!.physicsBody?.affectedByGravity = false
            rowTripLine!.physicsBody?.categoryBitMask = ColliderType.TripRow
            rowTripLine!.physicsBody!.collisionBitMask = 0
            rowTripLine!.physicsBody?.dynamic = true

            rowTripLine!.anchorPoint = CGPoint(x: 0, y: 0)
            self.addChild(rowTripLine!)
        } else {
            //col
            colTripLine = SKSpriteNode()
            colTripLine!.color = UIColor.redColor()

            //colTripLine!.position = CGPoint(x: xPos, y: 0);
            colTripLine!.size = CGSize(width: 1, height: Int(size.height))

            //borderLeft!.physicsBody = SKPhysicsBody(rectangleOfSize: size, center: CGPointMake(reducedSize/2, reducedSize/2))
            colTripLine!.physicsBody = SKPhysicsBody(rectangleOfSize: colTripLine!.size, center: CGPointMake(colTripLine!.size.width/2, colTripLine!.size.height/2))
            colTripLine!.physicsBody?.affectedByGravity = false
            colTripLine!.physicsBody?.categoryBitMask = ColliderType.TripColumn
            colTripLine!.physicsBody!.collisionBitMask = 0
            colTripLine!.physicsBody?.dynamic = true

            colTripLine!.anchorPoint = CGPoint(x: 0, y: 0)
            self.addChild(colTripLine!)
        }

    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init coder not implemented")
    }
}

我在主场景中生成如下的HeadTripper线:

for var i = 0; i < rowCount; i++ {

    let rowTrip = HeadTripper(size: size, rowOrCol: 0)
    rowTrip.id = i
    rowTrip.position.x = 0
    rowTrip.position.y = CGFloat(yVal)
    self.addChild(rowTrip)

    rowLines.append(CGFloat(rowTrip.position.y))
    CGPathMoveToPoint(linePath, nil, 0, CGFloat(yVal))
    CGPathAddLineToPoint(linePath, nil, CGFloat(theGrid.screenWidth), CGFloat(yVal))
    yVal += (theGrid.snakeHigh + yValPad)

}

以下是对撞机类型的设置方法:

struct ColliderType {
    static let Head:          UInt32 = 0
    static let Food:          UInt32 = 0b1
    static let Body:          UInt32 = 0b10
    static let BodyStatic:    UInt32 = 0b100
    static let WallLeft:      UInt32 = 0b1000
    static let WallBottom:    UInt32 = 0b10000
    static let WallRight:     UInt32 = 0b100000
    static let WallTop:       UInt32 = 0b1000000
    static let None:          UInt32 = 0b10000000
    static let Canvas:        UInt32 = 0b100000000
    static let TripColumn:    UInt32 = 0b1000000000
    static let TripRow:       UInt32 = 0b10000000000
}

tripRow让设置发生在第310行。在第309行,我可以看到contact.bodyA:

0x000000012758db20
 {
  NSObject = {
    isa = 0x000000012758db20
  }
  _representedObject = 0x00000001275765a0
  _field = 0x0000000000000000
  _dynamicType = 2
  _world = 0x0000000127761b90
  _joints = 0x0000000127576270 "0 values"
  _inUse = true
  _shapeType = 2
  _radius = 0
  _edgeRadius = 0.0010000000474974513
  _mask = 0x0000000000000000
  _isPinned = false
  _allowsRotation = true
  _postStepBlock = 0x000000019e666c70
}

我也可以看到contact.bodyA.node:

0x00000001275765a0
 {
  UIKit.UIResponder = {...}
}

第311行永远不会被调用,因为它处于不通过的if条件中。

在第313行,我尝试查看tripRow并获取此信息:

(lldb) po tripRow
error: <EXPR>:1:1: error: use of unresolved identifier 'tripRow'
tripRow

听起来问题与HeadTripper中的孩子有关。我把这些孩子命名为#34; row&#34;和&#34; col&#34;分别

print("body A name ", contact.bodyA.node?.name)
let tripRow = contact.bodyA.node as? SKSpriteNode

这给出了&#34; row&#34;的名称。此外,tripRow现在打印为:

(lldb) po tripRow
0x0000000155e737c0
 {
  SpriteKit.SKNode = {...}
}

我认为这非常接近。问题仍然存在,即位置不准确。 y值应该是54之类的数字,它是零:

(lldb) po tripRow?.position
(x = 0, y = 0)

1 个答案:

答案 0 :(得分:1)

这是通过在HeadTripper SKNode类中仅引用1个SKSpriteNode而不是2来解决的。