有效地检测碰撞

时间:2016-06-27 14:32:13

标签: ios swift sprite-kit

我已经尝试了几种不同的方法来检测didBeginContact方法中的冲突,但我不确定哪一种更有效 - 我正在尝试减少帧率下降。

方法1:

if let thisMine = nodeA as? Mine {
        if let thisPlayer = nodeB as? Player {
           thisMine.explode()
           thisPlayer.takeDamage(thisMine.damage)
       }
    }
    else if let thisMine = nodeB as? Mine {
        if let thisPlayer = nodeA as? Player {
           thisMine.explode()
           thisPlayer.takeDamage(thisMine.damage)
       }
    }

我在didBeginContact方法中使用不同的类多次这样做,因为我有很多可以互相交互的不同对象。

方法2(Steve Ives建议修改):

let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask

    switch contactMask {

    case CollisionCategoryPlayer | CollisionCategoryMine:
       let mineNode = contact.bodyA.categoryBitMask == CollisionCategoryMine ? contact.bodyA.node as! Mine : contact.bodyB.node as! Mine
       let playerNode = contact.bodyA.categoryBitMask == CollisionCategoryPlayer  ? contact.bodyA.node as! Player : contact.bodyB.node as! Player

       mineNode.explode()
       playerNode.takeDamage(mineNode.damage)

    default :
       print("Unregistered contact")
}  

使用此方法,我必须将联系人身体节点转换为播放器/我的/其他类,以便访问其属性和功能。这比比较方法1中的节点类更有效吗?我想使用switch语句而不是一堆if语句会更有效吗?

注意:这是Most Efficient Way to Check Collisions in didBeginContact

的后续问题

1 个答案:

答案 0 :(得分:1)

如果频繁发生碰撞或者如果有超过这两个类,你肯定应该使用方法2。

原因非常明显:此处的or - 操作和switch语句可以在恒定时间内执行。虽然as?运算符可以在O(n)O(log2(n))执行(完全取决于Swift运行时环境使用的任何内容,但O(1),但不太可能)。

如果您希望高性能代码和对象经常发生冲突,请选择两个。如果对象很少发生冲突,而您更喜欢非常清晰的代码,那么方法一可能是一种选择。