确定哪个sprite节点被命中

时间:2015-03-03 16:26:43

标签: swift sprite-kit

我希望能够识别当用户在一组目标精灵上抛弃另一个精灵时,命中了哪个精确的目标精灵节点。以下是我在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)
}

我能够检测到碰撞,但无法检索可识别哪个精确的ballNode被攻击的附加userData。当我尝试以下代码时,它只返回“nil”的输出。

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

2 个答案:

答案 0 :(得分:1)

我假设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)
        }
}

答案 1 :(得分:0)

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

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