确定哪个精灵节点被击中

Identify which sprite node was hit

我希望能够确定当用户向一组目标 sprite 投掷另一个 sprite 时,哪个确切的目标 sprite 节点被击中。这是我在 didMoveToView 函数下设置我的精灵的方法(这里只包括相关的代码行)

let flingerTexture = SKTexture(imageNamed: "flinger")
flingerNode.position = CGPoint(x: 768, y: 440)
flingerNode.physicsBody = SKPhysicsBody(texture: flingerTexture, size: flingerNode.size)
flingerNode.physicsBody?.dynamic = true
flingerNode.physicsBody!.categoryBitMask = PhysicsCategory.Flinger
flingerNode.physicsBody!.collisionBitMask = PhysicsCategory.Edge | PhysicsCategory.Bubble | PhysicsCategory.Ball
flingerNode.physicsBody?.contactTestBitMask = PhysicsCategory.Ball
let rotationConstraint = SKConstraint.zRotation(SKRange(lowerLimit: -π/4, upperLimit: π/4))
flingerNode.constraints = [rotationConstraint]
addChild(flingerNode)

// -------------Setup targets---------------
let range: Range<Int> = 1...10
for numbers in range {
    let ballNode: BallNode = BallNode(imageNamed: "\(numbers)a")
    let positionX = CGFloat.random(min: size.width / 6, max: size.width * 5/6)
    let positionY = CGFloat.random(min: size.height * 4/9, max: size.height * 8/9)
    ballNode.position = CGPoint(x: positionX, y: positionY)
    ballNode.name = "Ball"
    ballNode.ballIndex = Int(numbers)
    index = ballNode.ballIndex
    ballNode.ballHit = false
    addChild(ballNode)

    ballNode.physicsBody = SKPhysicsBody(circleOfRadius: 100)
    ballNode.physicsBody!.affectedByGravity = false
    ballNode.physicsBody?.dynamic = true
    ballNode.physicsBody!.restitution = 0.5
    ballNode.physicsBody!.friction = 0.0
    ballNode.physicsBody!.categoryBitMask = PhysicsCategory.Ball
    ballNode.physicsBody!.collisionBitMask = PhysicsCategory.Ball | PhysicsCategory.Bubble | PhysicsCategory.Edge | PhysicsCategory.Flinger | PhysicsCategory.Wall
    ballNode.physicsBody?.contactTestBitMask = PhysicsCategory.Flinger

    ballNode.userData = NSMutableDictionary()
    ballArray.append(ballNode.ballIndex)
}

我能够检测到碰撞,但无法检索到额外的 userData 来识别哪个 ballNode 被击中。当我尝试下面的代码时,它只有 returns "nil".

的输出
func didBeginContact(contact: SKPhysicsContact!) {
let collision = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
if collision == PhysicsCategory.Flinger | PhysicsCategory.Ball {
println(ballNode.userData)
}
}

我假设 PhysicsCategory.Flinger 小于 PhysicsCategory.Ball。然后在didContactBegan中你可以使用这个代码。

func didBeginContact(contact: SKPhysicsContact) {

    var body1 : SKPhysicsBody!
    var body2 : SKPhysicsBody!

    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
        body1 = contact.bodyA
        body2 = contact.bodyB
    }
    else  {
        body1 = contact.bodyB
        body2 = contact.bodyA
    }

    if body1.categoryBitMask == PhysicsCategory.Flinger &&
        body2.categoryBitMask == PhysicsCategory.Ball {

            if let ballNode = body2.node {

                println(ballNode.userData)
            }
    }

}

如果 PhysicsCategory.Flinger 大于 PhysicsCategory.Ball,则必须反转条件。

if body1.categoryBitMask == PhysicsCategory.Ball &&
    body2.categoryBitMask == PhysicsCategory.Flinger {

        if let ballNode = body1.node {

            println(ballNode.userData)
        }
}

非常感谢@rakeshbs 为我指明正确的方向!您的 didBeginContact 方法有效 - 问题是我没有正确添加 userData。我通过将以下行添加到我的 didMoveToView 函数来解决这个问题:

    ballNode.userData = ["ballNumber" : ballNode.ballIndex]