我已经尝试了几种不同的方法来检测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
的后续问题答案 0 :(得分:1)
如果频繁发生碰撞或者如果有超过这两个类,你肯定应该使用方法2。
原因非常明显:此处的or
- 操作和switch语句可以在恒定时间内执行。虽然as?
运算符可以在O(n)
或O(log2(n))
执行(完全取决于Swift运行时环境使用的任何内容,但O(1)
,但不太可能)。
如果您希望高性能代码和对象经常发生冲突,请选择两个。如果对象很少发生冲突,而您更喜欢非常清晰的代码,那么方法一可能是一种选择。