来自Texture的SKPhysicsBody在Spritekit中的碰撞时为null

时间:2016-05-01 18:59:30

标签: ios swift sprite-kit skspritenode skphysicsbody

我正在制作一个角色跳跃并收集点数的游戏(SOME OBJECT)。当您点击角色时,从地图集执行一些动画。当它接触点数时,得分增加1.我使用SKTexture创建角色的物理体。当我的角色触及点时,它会崩溃并向我显示此错误

fatal error: unexpectedly found nil while unwrapping an Optional value 

//代码

 Cat = SKSpriteNode(imageNamed: "cat");
  Cat.size = CGSize(width: 100, height: 100)
  Cat.position = CGPoint(x: self.frame.width/2, y: self.frame.height/2)

  //physics 
  Cat.physicsBody = SKPhysicsBody(texture: SKTexture(imageNamed: "cat"), size:CGSizeMake(100, 100))

但是如果我从矩形或圆形创建Physicsbody就可以了。也许它与我用于动画我的角色的地图集有关。

Cat.physicsBody = SKPhysicsBody(circleOfRadius: self.frame.width/2)

当角色接触蘑菇时,它会崩溃。 工作演示: https://github.com/nak1b/demo-game-error

1 个答案:

答案 0 :(得分:2)

您的代码的问题是多次调用didBeginContact ...您可以通过在print()块中放置if语句来检查此问题。

如您所知,SKPhysicsBody对象具有名为node的属性。这是一个可选的属性。它表示此主体连接到的节点。在你的情况下,这是一个蘑菇节点。

因此,当第一次调用didBeginContact时,因为您从其父项中删除了一个蘑菇节点,bodyA.node变为nil。下次执行bodyA.node!.removeFromParent()会导致崩溃,因为正如我所说,bodyA.node现在为零,但您正在使用强制解包来访问可选的基础值。

仅当您100%肯定基础值不为零时(或者如果您有意在开发阶段触发错误),才使用强制解包。否则使用可选绑定或可选链接。像这样:

func didBeginContact(contact: SKPhysicsContact) {

    var firstBody, secondBody: SKPhysicsBody

    //Do this to avoid double checking
    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {

        firstBody = contact.bodyA
        secondBody = contact.bodyB
    } else {

        firstBody = contact.bodyB
        secondBody = contact.bodyA
    }

    //No need for double-checking now
    if ((firstBody.categoryBitMask & PhysicsCategory.Panda) != 0 &&
        (secondBody.categoryBitMask & PhysicsCategory.Score != 0)) {

            //This will fail gracefully if node property is nil
            secondBody.node?.removeFromParent()
    }
}