2016-06-27 1 views
3

J'ai essayé deux méthodes différentes pour détecter les collisions dans la méthode didBeginContact, mais je ne suis pas sûr de savoir laquelle est la plus efficace - j'essaie de réduire mes chutes de fréquence d'images.Détection efficace des collisions

Méthode 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) 
     } 
    } 

Je fais cela un tas de fois en utilisant différentes classes dans la méthode didBeginContact parce que j'ai beaucoup d'objets différents qui peuvent interagir les uns avec les autres.

Méthode 2 (suggérée par Steve Ives avec des 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 

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

    default : 
     print("Unregistered contact") 
} 

Avec cette méthode, je dois jeter les nœuds du corps de contact en tant que joueur/moi/autre classe afin d'accéder à leurs propriétés et fonctions . Est-ce encore plus efficace que de comparer les classes du nœud comme dans la méthode 1? J'imagine qu'il est plus efficace d'utiliser l'instruction switch plutôt qu'un tas d'instructions if?

Note: ceci est une question de suivi à Most Efficient Way to Check Collisions in didBeginContact

+0

Les questions sur les «meilleures pratiques» ne sont pas adaptées au débordement de la pile, essayez peut-être de demander l'échange de révision de code. http://codereview.stackexchange.com/ Note: vous devez demander 'Est-ce que ce code suit les meilleures pratiques?', pas 'Quelle est la meilleure pratique?' – Knight0fDragon

Répondre

1

Vous devriez certainement aller avec la méthode 2 si les collisions se produisent fréquemment ou s'il y a plus de ces deux classes. Les raisons en sont très évidentes: L'opération or et votre instruction switch peuvent être exécutées à temps constant. Alors que l'opérateur as? peut effectuer à O(n) ou O(log2(n)) (dépend complètement de tout ce que l'environnement d'exécution Swift emploie, O(1), cependant, est très improbable).

Si vous voulez que le code performant et les objets se heurtent souvent, optez pour deux. Cependant, si les objets se heurtent très rarement et que vous préférez un code très clair, la méthode un peut être une option.

+0

ne code pas 2 effectuer les mêmes types de contrôles que le code 1 , avec l'ajout d'un commutateur et ou – Knight0fDragon

+0

Merci pour la réponse. Est-ce la même chose pour quand je lance en utilisant l'as! au lieu de comme? Puisque j'ai besoin de lancer un cours en utilisant as! accéder aux propriétés/fonctions, cela ruinera-t-il la performance de la méthode 2? – claassenApps

+1

@ Knight0fDragon C'est vrai. Mais ces vérifications (elles sont probablement supprimées en mode release à cause du '!') Ne sont effectuées que si la collision est réellement intéressante alors que dans le code 1 ces vérifications sont effectuées chaque fois que deux objets entrent en collision. – idmean