2016-12-22 44 views
1

我有一個Bullets和Enemies對象的數組。我希望遊戲檢查數組中的每個元素,看看兩者之間是否有碰撞。如果發生任何碰撞,則傷害敵人並刪除子彈。現在每次子彈擊中敵人時,它都會降低陣列中所有敵人的健康,從而一次殺死所有敵人。我怎麼能這樣做,它只會減少我射擊的敵人的健康狀況?如何檢測陣列中兩個對象之間的碰撞(Sprite Kit)

//This function handles our collision detection 
    func didBegin(_ contact: SKPhysicsContact) { 
     //print("COLLISIONS!") 
     // If contact is with another object 
     if contact.bodyA.categoryBitMask == pickupCategory && contact.bodyB.categoryBitMask == playerCategory 
     { 
      displayText(text: "Picked up Pistol") 
      player.setHasPistol(gotPistol: true) 
      pistol.removeFromParent() 
     } 

     //Bullet hits an object 
     if contact.bodyA.categoryBitMask == objectCategory && contact.bodyB.categoryBitMask == bulletCategory 
     { 
      bulletCleanup(killNow: true) 
      //print("BULLET HAS HIT THE PIPE!") 
     } 

     //Do collisions between bullets and enemies... 
     for bullet in bulletList 
     { 
      for enemy in enemyList 
      { 
       //if the enemy was hit have them take damage. 
       if contact.bodyA.categoryBitMask == enemyCategory && contact.bodyB.categoryBitMask == bulletCategory 
       { 
        //deletes the bullet after hitting an object 
        bulletCleanup(killNow: true) 

        //apply damage 
        enemy.setHitPoints(setPoints: enemy.getHitPoints() - pistol.getDamage()) 

        // print("BULLET HAS HIT THE enemy!!!!") 
       } 
      } 
     } 
    } 

回答

2

didBegin(contact:)被稱爲一個特定對象與另一個特定對象之間的單個衝突。 (物理機構之間其實...)

你的問題發生,因爲你是在迭代每子彈和敵人單個碰撞,並在每次迭代要測試是否有碰撞子彈之間一個敵人,它是,所以你正在對每個敵人施加傷害。

您只需從SKPhysicsContact對象中提取特定敵人並對該特定敵人造成傷害。

而且,我懷疑你是缺少一些接觸,因爲你接觸的測試,如果bodyAbodyB物理機構被顛倒,即

if contact.bodyA.categoryBitMask == pickupCategory && contact.bodyB.categoryBitMask == playerCategory 

bodyA可能是playerbodyB可能是pickup你不檢查,所以你也需要測試一下。

這裏是一個另類didBegincontact()你可能會發現有用的(這是Swift2,但是這不應該是一個很大的問題):

func didBeginContact(contact: SKPhysicsContact) { 
    let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask 

switch contactMask { 

    case pickupCategory | playerCategory 
     displayText(text: "Picked up Pistol") 
     player.setHasPistol(gotPistol: true) 

     let pistol = (contact.bodyA.categoryBitMask == pickupCategory) ? contact.bodyA.node! : contact.bodyB.node! 

     pistol.removeFromParent() 

    case objectCategory | bulletCategory 
     bulletCleanup(killNow: true) 
     //print("BULLET HAS HIT THE PIPE!") 

    case enemyCategory| bulletCategory 

     //deletes the bullet after hitting an object 
     bulletCleanup(killNow: true) 

     //apply damage 
     let enemy = (contact.bodyA.categoryBitMask == enemyCategory) ? contact.bodyA.node! : contact.bodyB.node! 
     enemy.setHitPoints(setPoints: enemy.getHitPoints() - pistol.getDamage()) 

    default : 
     //Some other contact has occurred 
     print("Some other contact") 
    } 
} 

我不知道你的bulletCleanup()功能是如何工作的 - 你不似乎是發送一個特定的子彈對象,所以我不知道它是如何知道要處理的子彈。 ?參與接觸的特定子彈可以在didBegincContact:如下獲得:

 let bullet = (contact.bodyA.categoryBitMask == bulletCategory) ? contact.bodyA.node! : contact.bodyB.node! 

這是說短形式「是nodeAcategoryBitMask一個bulletCategory如果是,則設置bullet等於nodeA,否則設置bulletnodeB

請注意,如果您的類別比較複雜(即對象可以屬於多個類別),這將不會是簡單和試驗(enemyCategory| bulletCategory)工作將不匹配。

+0

你可能也想問自己爲什麼你要保持子彈和敵人的陣列。您可能有一個非常真實的原因,但有其他方法來訪問這些節點 - SKScene的children []屬性和enumerateChildNodesWithName()函數來命名,但是2. –

+0

嘿,人感謝您的迴應!對此,我真的非常感激!現在我知道爲什麼我的碰撞只發生在一半的時間!然而,我仍然不理解這個部分,「你只需要從SKPhysicsContact對象中提取特定的敵人並對該特定的敵人施加傷害。」我怎麼做,而不是迭代通過我的數組?在你的例子中,你有「enemy.setHitPoints(setPoints:enemy.getHitPoints() - pistol.getDamage())」。那麼,我如何告訴函數「敵人」是什麼或者我正在談論哪一個。 –

+0

@SamTrent SKOhysics聯繫人有2個屬性 - bodyA和bodyB。這些是物理體,每一個都有一個屬性「節點」,它是與該物理體相關的節點。因此,代碼行'let enemy = contact.bodyA.categoryBitMask == enemyCategory? contact.bodyA ....'會創建一個與衝突中涉及的實際敵人相同的臨時SKNode。 –