我正在制作一个角色跳跃并收集点数的游戏(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
答案 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()
}
}