如何检测数组中两个对象之间的冲突(Sprite Kit)

时间:2016-12-22 00:58:48

标签: arrays collections 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!!!!")
                }
            }
        }
    }

1 个答案:

答案 0 :(得分: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!

这是一种简短形式的说法"是nodeA' s categoryBitMaskbulletCategory?如果是,则将bullet设置为nodeA,否则将bullet设置为nodeB

请注意,如果您的类别更复杂(即对象可以属于多个类别),那么这不会起作用,因为简单的AND测试(enemyCategory| bulletCategory)不匹配。