2016-06-27 5 views
3

Я пробовал несколько разных методов обнаружения столкновений в методе 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

Вопросы «Лучшая практика» не подходят для переполнения стека, возможно, попробуйте обменяться просмотром кода. http://codereview.stackexchange.com/ Примечание: вам нужно спросить: «Этот код соответствует лучшей практике?», а не «Какая практика?» – Knight0fDragon

ответ

1

Вы определенно должны идти с методом 2, если столкновения происходят часто или если есть больше, чем эти два класса.

Причины этого очень очевидны: or -операция и инструкция переключателя здесь могут быть выполнены в постоянное время. Принимая во внимание, что оператор as? может выполнять на O(n) или O(log2(n)) (полностью зависит от того, что использует рабочая среда Swift Runtime Environment, O(1), однако, маловероятно).

Если вы хотите, чтобы исполняемый код и объекты сталкивались часто, перейдите к двум. Если объекты сталкиваются очень редко, и вы предпочитаете очень четкий код, метод может быть вариантом.

+0

не кодирует код 2, выполняет те же типы проверок, что и код 1 , с добавлением переключателя и/или – Knight0fDragon

+0

Спасибо за ответ. То же самое можно сказать и о том, когда я использую as! а не как? Так как мне нужно бросить класс, используя как! для доступа к свойствам/функциям, разрушит ли производительность метода 2? – claassenApps

+1

@ Knight0fDragon Правильно. Но эти проверки (они скорее всего удалены в режиме выпуска из-за '!') Выполняются только в том случае, если столкновение действительно представляет интерес, тогда как в коде 1 эти проверки выполняются каждый раз, когда сталкиваются два объекта. – idmean

Смежные вопросы