我尝试了几种不同的方法来检测 didBeginContact 方法中的碰撞,但我不确定哪种方法更有效 - 我正在尝试减少帧速率下降。
方法一:
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 的后续问题
最佳答案
如果碰撞频繁发生或者碰撞不止这两个类,您绝对应该使用方法 2。
这样做的原因很明显:or
操作和这里的switch语句可以在常量时间内执行。而 as?
运算符可以在 O(n)
或 O(log2(n))
执行(完全取决于 Swift 运行时环境雇用,O(1)
,然而,这是非常不可能的)。
如果您希望高性能代码和对象经常发生冲突,请选择两个。但是,如果对象很少发生碰撞并且您更喜欢非常清晰的代码,则方法一可能是一种选择。
关于ios - 有效检测碰撞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38056674/