首页 文章

SpriteKit崩溃:物理体如何失去与SKNode的关联?

提问于
浏览
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)物理体如何在没有节点的情况下甚至存在?

2 回答

  • 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
    }
    
  • 1

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

    在您的 didBallTileHit() 中,您是否 removeFromParent() 任何节点?如果是这样,这可能是导致崩溃的原因,因为Sprite-Kit在2个对象之间产生了多次冲突,并且对于2个节点多次调用 didBegin() . 如果您然后将第一次调用中的一个节点移除到 didBegin() ,那么第二次和后续调用将不会存在 .

    处理它的方法(你不能让sprite-kit在某些情况下多次调用didBegin)是为了确保你的联系代码适应这种情况并且多次处理 Contract 不会导致问题(例如添加分数多次,删除多个生命,试图访问已被删除的节点或物理体等) .

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

相关问题