2016-05-01 13 views
1

キャラクターがジャンプしてポイント(一部のオブジェクト)を収集するゲームを作成しています。キャラクターをタップすると、アトラスからいくつかのアニメーションを実行します。ポイントにタッチすると、スコアが1ずつ増加します。SKTextureを使用してキャラクターの物理学者を作成しています。私のキャラクターがポイントに触れると、それがクラッシュし、私は、このエラーを表示//コードTextureのSKPhysicsBodyはSpritekitの衝突でnullを返します

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)) 

fatal error: unexpectedly found nil while unwrapping an Optional value 

をしかし、私は、矩形や円からPhysicsbodyを作成する場合、それだけで正常に動作します。私のキャラクターをアニメーション化するために使用しているアトラスを使っているかもしれません。

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

キノコに触れるとクラッシュします。 ワーキングデモ:https://github.com/nak1b/demo-game-error

+0

を参照してください:http://stackoverflow.com/a/36610484/3402095 – Whirlwind

+0

@Whirlwindそれは大丈夫 – Nakib

+0

を助けるdidntのため、コードのクラッシュのどのライン? – Whirlwind

答えて

2

あなたのコードに問題がdidBeginContactが複数回呼び出されているということです...あなたはそのifブロックの内側にprint()文を置くことによってこれを確認することができます。

SKPhysicsBodyオブジェクトには、nodeというプロパティがあります。これはオプションのプロパティです。この本体が接続されているノードを表します。あなたのケースでは、キノコのノードです。

didBeginContactが初めて呼び出されたとき、マッシュルームノードをその親から削除するため、bodyA.nodenilになります。次回は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() 
    } 
} 
+0

あなたの助けを借りてくれてありがとう。私はこれを試し、役に立つ答えとしてマークします。物理学の本文が円または四角形を使用して割り当てられている場合、これがなぜ機能するのか説明できますか? – Nakib

+0

@Nakib SpriteKitが内部でさまざまな形状の物理体の接触検出を処理する方法は文書化されていないので、詳しくは説明できません...あなたのケースでは、私が見ることができるのは、 'didBeginContact'が直方体を作成します。したがって、 'bodyA.node'が' nil'である状況に遭遇することはありません。だから、それは動作する(クラッシュしないことを意味する)。それでも、あなたが見ることができるように、強制アンラッピングは最も安全な方法ではありません。 – Whirlwind

+0

これはクラッシュを修正しましたが、私はdidbeginContact内にscoreGenerator()を持っています。きのこが取り除かれると、それはランダムな位置で再び生成されます。コードを上に変更すると、その関数が継続的に呼び出されます。 – Nakib

関連する問題