命中致命错误:在展开Optional值(lldb)时意外发现nil

时间:2015-05-04 12:57:40

标签: swift sprite-kit

我编写了一个简单的游戏,在第一次碰撞时我收到以下错误:

  

命中致命错误:在解包可选值(lldb)时意外发现nil

这是我的代码:

func didBeginContact(contact: SKPhysicsContact) {

    var firstBody: SKPhysicsBody
    var secondBody: SKPhysicsBody

    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
        firstBody = contact.bodyA
        secondBody = contact.bodyB

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

    if ((firstBody.categoryBitMask & PhysicsCategory.Monster != 0) &&
        (secondBody.categoryBitMask & PhysicsCategory.naboj != 0)) {
            projectileDidCollideWithMonster(firstBody.node as SKSpriteNode, monster: secondBody.node as SKSpriteNode)

    }

}

4 个答案:

答案 0 :(得分:5)

之前我遇到过同样的问题,这就是我做的事情

基本上,当您解开物理主体时(这通常发生在secondBody.node!行),会发生以下情况:

  1. 如果您有3个碰撞的实体(abc),并且碰撞逻辑适用于所有3个,则sprite套件将执行2次碰撞检查:< / p>

    • 一个有身体ab
    • 的人
    • 然后使用正文bc
  2. 你在碰撞中移除尸体:

    • 首次检测:正文ab已解包,正文ab已被删除

      < / LI>
    • 第二次检测:仅剩下正文c,因为ab已被删除。这意味着secondBodyfirstBody现在为零。所以错误被抛出

  3. 尝试将代码更改为以下内容,它应解决问题:

    var firstBody: SKPhysicsBody?
    var secondBody: SKPhysicsBody?
    
    if (firstBody!.node! != nil && secondBody!.node! != nil) {
           if ((firstBody.categoryBitMask & PhysicsCategory.Monster != 0) &&
                    (secondBody.categoryBitMask & PhysicsCategory.Projectile != 0)) {
                    projectileDidCollideWithMonster(secondBody.node!, monster: firstBody.node!)
            }
    }
    

答案 1 :(得分:2)

您使用的是swift 1还是1.2?

尝试

if ((firstBody.categoryBitMask & PhysicsCategory.Monster != 0) &&
    (secondBody.categoryBitMask & PhysicsCategory.naboj != 0)) {

    if let firstNode = firstBody.node as? SKSprintNode,
       let secondNode = secondBody.node as? SKSprinteNode {

       projectileDidCollideWithMonster(firstNode, monster: secondNode)
    }
}

答案 2 :(得分:0)

尝试这种方式:

if ((firstBody.categoryBitMask & PhysicsCategory.Monster != 0) &&
    (secondBody.categoryBitMask & PhysicsCategory.naboj != 0)) {
    if(firstBody.node != nil && secondBody.node != nil ) {
        projectileDidCollideWithMonster(firstBody.node as SKSpriteNode, monster: secondBody.node as SKSpriteNode) }
}

答案 3 :(得分:0)

好的,这花了我一段时间才弄清楚,但最后得到了它。我尝试了大多数其他解决方案,我可以在网上找到,运气很少。我必须努力解决这个问题。你需要做的是如果找到零,则给出中断/返回的选项。因为大多数情况下,当同时触发两个相同的碰撞时会发生此错误。

我做的是如果出现nil,则使用if else语句返回函数。

func didBeginContact(contact: SKPhysicsContact) {

var firstBody: SKPhysicsBody
var secondBody: SKPhysicsBody

if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
    firstBody = contact.bodyA
    secondBody = contact.bodyB

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

if ((firstBody.categoryBitMask & PhysicsCategory.Monster != 0) &&
    (secondBody.categoryBitMask & PhysicsCategory.naboj != 0)) {
// new part
    if (firstBody.node == nil || secondBody.node == nil)
    {return}

else {
 projectileDidCollideWithMonster(firstBody.node as SKSpriteNode, monster: secondBody.node as SKSpriteNode)
}}}

我希望这会有所帮助。 通过在if而不是else中使用return语句来对待它也很重要。