0

此代码崩溃,因为secondBody未与节点关联。

func didBegin(_ contact: SKPhysicsContact) {
    // Set vars to hold bodies
    var firstBody: SKPhysicsBody
    var secondBody: SKPhysicsBody

    // Sort bodies
    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
        firstBody = contact.bodyA
        secondBody = contact.bodyB
    } else {
        firstBody = contact.bodyB
        secondBody = contact.bodyA
    }

    // Handle different contacts
    if firstBody.categoryBitMask == BallBitMask && secondBody.categoryBitMask == TileBitMask {
        didBallTileHit(tile: secondBody.node!) // Code crashes here :(
    }

    ...
}

1) 除了将物理体设置为 之外nil,还有什么会导致物理体与 SpriteKit 中的节点失去关联?

2)一开始没有节点的物理体怎么可能存在?

4

2 回答 2

1

SKSPhysicsBody 本身就是一个对象,完全能够被创建但与 SKSpriteNode 无关(尽管可能没有多大用处:-))

在你的didBallTileHit(),你removeFromParent()有任何节点吗?如果是这样,这可能是您崩溃的原因,因为 Sprite-Kit 在 2 个对象之间产生了多次碰撞,并且didBegin()为 2 个节点调用了多次。如果您随后在第一次调用中删除其中一个节点,didBegin()则第二次和后续调用将不存在该节点。

处理它的方法(在某些情况下,您不能让 sprite-kit 多次调用 didBegin)是确保您的联系代码适应这一点,并且多次处理合同不会导致问题(例如添加多次得分,删除多个生命,尝试访问已删除的节点或物理体等)。

有关更多详细信息和可能的解决方案,请参阅此答案:https ://stackoverflow.com/a/44384390/1430420

于 2017-08-29T13:15:42.663 回答
1

您可以用不同的方法处理联系人。

对你来说更简单的方法是把这个:

func didBegin(_ contact: SKPhysicsContact) {

    let bodyA = contact.bodyA
    let bodyB = contact.bodyB

    guard let nodeA = bodyA.node as? SKSpriteNode,
          let nodeB = bodyB.node as? SKSpriteNode,
          let parentNodeA = nodeA.parent,
          let parentNodeB = nodeB.parent
    else {return}

    //all your stuff
}
于 2017-08-29T15:03:41.680 回答