Texture 中的 SKPhysicsBody 在 Spritekit 中碰撞时给出空值
SKPhysicsBody from Texture gives null on collision in Spritekit
我正在创建一个角色跳跃和收集点数的游戏(一些 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
您的代码的问题是 didBeginContact
被多次调用...您可以通过在 if
块中放置一个 print()
语句来检查这一点。
如您所知,SKPhysicsBody
object 有一个 属性 称为 node
。它是一个可选的 属性。它表示此 body 连接到的节点。在您的情况下,这是一个蘑菇节点。
所以当didBeginContact
第一次被调用时,因为你从它的parent中移除了一个蘑菇节点,bodyA.node
变成了nil
。下次执行 bodyA.node!.removeFromParent()
将产生崩溃,因为正如我所说,bodyA.node
现在为 nil 但您正在使用强制解包来访问可选的基础值。
仅当您 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()
}
}
我正在创建一个角色跳跃和收集点数的游戏(一些 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
您的代码的问题是 didBeginContact
被多次调用...您可以通过在 if
块中放置一个 print()
语句来检查这一点。
如您所知,SKPhysicsBody
object 有一个 属性 称为 node
。它是一个可选的 属性。它表示此 body 连接到的节点。在您的情况下,这是一个蘑菇节点。
所以当didBeginContact
第一次被调用时,因为你从它的parent中移除了一个蘑菇节点,bodyA.node
变成了nil
。下次执行 bodyA.node!.removeFromParent()
将产生崩溃,因为正如我所说,bodyA.node
现在为 nil 但您正在使用强制解包来访问可选的基础值。
仅当您 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()
}
}