2016-08-17 14 views
2

3体が一度に衝突してアプリがクラッシュすると、まれに発生する問題が発生しています。 3つの物体が一度に衝突しない限り、body1とbody2、またはbody1とbody3の間の衝突検出はうまくいきます(body2とbody3の衝突は問題ではなく、互いに右に通過できます)。それが起こるとき、私はこれらのエラーを取得:xcodeで3体衝突検出問題

fatal error: unexpectedly found nil while unwrapping an optional value

thread1: EXC_BAD_INSTRUCTION (code=EXC_1386_INVOP,subcode=0x0

すべてのヘルプははるかに高く評価されます。関連コードは以下です。

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.Enemy != 0) && 
     (secondBody.categoryBitMask & PhysicsCategory.Star != 0)) { 
     starDidCollideWithEnemy(firstBody.node as! SKSpriteNode, enemy: secondBody.node as! SKSpriteNode) 
    } 

    if ((firstBody.categoryBitMask & PhysicsCategory.Enemy != 0) && 
     (secondBody.categoryBitMask & PhysicsCategory.Flyer != 0)) { 
     flyerDidCollideWithEnemy(firstBody.node as! SKSpriteNode, enemy: secondBody.node as! SKSpriteNode) 
    } 

第三者の身体を追加する方法はありますか?あるいは、別の身体のケースに接触した身体の2つのケースを検出する何らかの方法ですか?

もっと遊んでいる私は、衝突するオブジェクトの1つのFromParentを削除しなければ、問題が解消されることを知りました。これはゲームには理想的ではありませんが、私はうまくいけば、このクラッシュをなくして、衝突するすべてのオブジェクトを取り除くことができればと思います。たぶん、親から関与しているすべての削除がありますか?

答えて

0

だから私は起こっていることはこれだと思います。

表示されているランタイムエラーは、nilを保持するオプションのアンラップを強制すると発生します。そして、あなたのスニペットでは、firstBodyとsecondBodyは、(型の注釈の '!'のために)定義によってアンラップされます。

私は、starDidCollideWithEnemyがシーンからfirstBodyまたはsecondBodyのいずれかを削除すると仮定しています。そうでなければ、それらを取り除く。

次に、二重衝突の場合、次のifブロックが評価されます。しかし、firstBodyかsecondBodyのどちらかがすでにゼロになっているので、全体が爆発します。

おそらく最も簡単なことは、最初のブロックのelseブロック内で2番目のテストを評価することでしょう。

if ((firstBody.categoryBitMask & PhysicsCategory.Enemy != 0) && 
     (secondBody.categoryBitMask & PhysicsCategory.Star != 0)) { 
     starDidCollideWithEnemy(firstBody.node as! SKSpriteNode, enemy: secondBody.node as! SKSpriteNode) 
    } 

    else if ((firstBody.categoryBitMask & PhysicsCategory.Enemy != 0) && 
     (secondBody.categoryBitMask & PhysicsCategory.Flyer != 0)) { 
     flyerDidCollideWithEnemy(firstBody.node as! SKSpriteNode, enemy: secondBody.node as! SKSpriteNode) 
    } 
+0

応答nckeのおかげで、私はelseを追加しようとしましたが、3つのボディがすべて同時に衝突するとクラッシュします。あなたは、starDidCollideWithEnemyが関与する2つの衝突するボディーを削除するという点で正しいです。それで、flyerDidCollideWithEnemyも同様です。たぶん、3つのボディの衝突をすべてテストする方法があります。もしそうなら、衝突に関係するすべてのボディを取り除くでしょうか? – spapp