claassenApps claassenApps - 3 months ago 12
Swift Question

Detecting Collisions Efficiently

I've tried a couple different methods for detecting collisions in the didBeginContact method, but I'm not sure which one is more efficient - I'm trying to cut down on my frame rate drops.

Method 1:

if let thisMine = nodeA as? Mine {
if let thisPlayer = nodeB as? Player {
else if let thisMine = nodeB as? Mine {
if let thisPlayer = nodeA as? Player {

I'm doing this a bunch of times using different classes in the didBeginContact method because I have lots of different objects that can interact with each other.

Method 2 (Suggested by Steve Ives with modifications):

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


default :
print("Unregistered contact")

With this method, I have to cast the contact body nodes as a player/mine/other class in order to access their properties and functions. Is this still more efficient than comparing the node's classes like in method 1? I imagine it's more efficient to use the switch statement rather than a bunch of if statements?

Note: this is a follow up question to Most Efficient Way to Check Collisions in didBeginContact


You should definitely go with method 2 if collisions occur frequently or if there are more than these two classes.

The reasons for this are very obvious: The or-operation and your switch statement here can be performed in constant time. Whereas the as? operator could perform at O(n) or O(log2(n)) (completely depends on whatever the Swift Runtime Environment employs, O(1), however, is very unlikely).

If you want performant code and objects collide often, go with two. If objects collide very rarely however and you prefer very clear code, method one might be an option.