ios - 有效检测碰撞

标签 ios swift sprite-kit

我尝试了几种不同的方法来检测 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/

相关文章:

ios - 只有根级导航目的地对具有同构路径的导航堆栈有效

ios - 如何产生跳跃的冲动

ios - 如何从 Sprite Kit 场景中引用当前的 Viewcontroller

ios - 在 swift spritekit 中正确呈现新场景

swift 3 : Dict from only one object in struct in array

ios - 将 UIView 转换为 SKView 时的程序集崩溃报告

ios - Firebase 推送通知 iOS

ios - Swift ios 使用 unix 时间戳

ios - 在保持用户位置居中的同时在 MKMapView 上安装注释

ios - NSDateFormatter 没有正确返回