2015-01-15 9 views
5
func didBeginContact(contact: SKPhysicsContact) { 
    if (contact.bodyA.categoryBitMask & BodyType.shield.rawValue) == BodyType.shield.rawValue { 
     contact.bodyB.node?.removeFromParent() 
     counter++ 
     println(counter) 


    } else if (contact.bodyB.categoryBitMask & BodyType.shield.rawValue) == BodyType.shield.rawValue { 
     contact.bodyA.node?.removeFromParent() 
     counter++ 
     println(counter) 
    } 
} 

一の物理本体は、テクスチャからなる同じSKPhysicsBodyに対して複数回呼び出されているshield.physicsBody = SKPhysicsBody(texture: shieldTexture, size: shieldTexture.size()) 他方は円sand.physicsBody = SKPhysicsBody(circleOfRadius: sand.size.width/2) didBeginContactは

トウは時々sand.physicsBody = SKPhysicsBody(circleOfRadius: sand.size.width/2) が呼び出さ互いに接触する物体からある

複数回。私はそれが接触するとすぐにそれを親から削除しても、各オブジェクトに対して一度だけ呼び出されるようにするにはどうすればよいですか。

+2

テクスチャからのボディが内部的に複数のシェイプを生成する可能性があり、それぞれが接触イベントを引き起こす可能性があるため、これは意図した通りに機能します。ノードを削除しても、物理シミュレーションのステップが終了するまでボディが削除されません。この連絡イベントで処理されたノードまたは本体を手動で「マーク」して、後で同じ本体の連絡イベントをスキップする必要があります。 – LearnCocos2D

+0

SKPhysicsBodyのテクスチャからのオプションがパラメータを介して設定されることを望みます。 circleOfRadiusのSKPhysicsBodyは、1つのヒット/コンタクトのみをカウントします。これは、以下の答えを含む余分なロジックを作成するよりも、たいへん望ましいでしょう。また、必要でない場合、連絡先を検出できないリソースを節約することができます。 –

答えて

2

func didBeginContact(contact: SKPhysicsContact)を1回だけ呼び出す方法を知りました。これにより、実際に(テクスチャの物理的性質の性質のために)この関数が複数回呼び出されても、テクスチャSKPhysicsBody(texture: size:)を持つフィジックスボディが一度衝突をカウントすることができます。

ステップ1:

(私たちはこの例のためにボールを使用します)SKSpriteNodeの名前のプロパティを作成し、一意の名前とそれが等しくなるように設定。

var number = 0 

ball.name = "ball \(number)" 

これにより、オブジェクトが作成される一意の名前evertimeが可能になります。

ステップ2:

番号をインクリメントし、配列にボールを追加し、これらを保持する配列を作成します

var array: [String] = [] 
    var number = 0 

ball.name = "ball \(number)" 
array.append(ball.name!) 
number ++ 

ステップ3:名前がでている場合は今func didBeginContact(contact: SKPhysicsContact)で見つけますアレイ。スコアをインクリメントする場合は、ノードを削除し、配列から名前を削除します。名前が配列にない場合は、何もしないでください。

配列から名前を削除することで、関数呼び出しを1回だけカウントすることができます。

func didBeginContact(contact: SKPhysicsContact) { 
    if (contact.bodyA.categoryBitMask & BodyType.shield.rawValue) == BodyType.shield.rawValue { 
     var name = contact.bodyB.node?.name! 
     let index = find(array, name!) 

     if contains(array, name!) { 
      score++ 
      contact.bodyB.node?.removeFromParent() 
      array.removeAtIndex(index!) 
     } 
    } 
} 
+1

SKSpriteNodeを配列に追加できませんか?私たちがそれらを比較できるように、参照によって渡された、私はなぜ私たちが一意の名前を割り当てる必要があるかわかりません。 – 3366784

0

LearnCocos2Dは右である、SKPhysicsbody didBeginContactは限り我々はSKPhysicsBody(texture:xxx, size:xx)で許可された形状は、複数のフォームと形で来ることができるので、二つのオブジェクトのSKphysicsbodyが接触しているよう継続的に呼び出します。

一度だけ検出する必要がある人には、検出が完了したかどうかを確認するフラグとしてブール値を使用する必要があります。

  1. varブール宣言します:ここで

    が、私はそれを行う方法である

    var contactDone = Bool() 
    
  2. は、プログラムの開始時に、それを初期化する(例えば、didMoveToView以下)

    contactDone = false 
    
  3. didBeginContactでチェック行います

    func didBeginContact(contact:SKPhysicsBody){ 
    
    if((contact.bodyA.categoryBitMask) == scoreCategory ||  (contact.bodyB.categoryBitMask) == scoreCategory){ 
    
         if (contactDone == false){ 
    
         // Increment score   
         score++ 
    
         // Set flag to disable multiple calls by checking in didEndContact 
         contactDone = true 
    
         } 
    } 
    } 
    
  4. クリアそれはdidEndContactに再びチェックしてみましょうするフラグ:

    func didEndContact(contact: SKPhysicsContact) { 
    
    if((contact.bodyA.categoryBitMask) == scoreCategory || (contact.bodyB.categoryBitMask) == scoreCategory){ 
    
          if(contactDone == true){ 
    
           contactDone = false 
    
          } 
    
    } 
    
    } 
    

それは同じように働いていたが私がSKPhysicBody(circleOfRadius: object.size.height/2)を使用したときにしました。

+0

'SKPhysicsBody(texture:ghostTexture、size:Obj.size)'を使用すると動作しません – Danny182

0

この場合、配列なしで動作させることができます。この代わりに:

contact.bodyA.node?.removeFromParent() 
counter++ 

使用このような何か:あなたはif文で後続の呼び出しコードで、親からノードを削除する最初の接触で

if let node = contact.bodyA.node as? SKSpriteNode { 
    if node.parent != nil { 
     node.removeFromParent() 
     counter++ 
    } 
} 

はスキップされます。

1

あなたがcontactbitmaskを使用してキャプチャする衝突を判断する場合、非常に簡単な解決策があります。

繰り返し検出したくないオブジェクトのcategoryBitMaskを、使用されていない新しい値に更新するだけで、システムは関連する後続の関数呼び出しをもう考慮しません。

関連する問題