2016-08-21 6 views
11

Я пытаюсь использовать коллизий битовые маски и контакта тест битовых масок в Swift, я хочу два объекта, чтобы не сталкиваться друг с другом, так что я делаю:Не могу понять, как столкновение битовая маска работает

firstNode.physicsBody?.collisionBitMask = 0b01 
secondNode?.collisionBitMask = 0b10 

С SpriteKit выполняет операцию AND на этих двух номерах, не должен ли результат 00 с 10 & 01 = 00?

Так почему же столкновения происходят в любом случае?

спасибо.

ответ

7

Это не так, как работает столкновение. Когда два тела находится в пересечении, физический движок выполняет логический оператор AND между телом collisionBitMask и другим телом текущего в categoryBitMask:

Когда две физических тела контактируют друг с другом, столкновение может произойти. Маска столкновения этого тела сравнивается с маской другого тела , выполняя логическую операцию И. Если результатом является ненулевое значение , на это тело влияет столкновение. Каждый орган независимо выбирает, хочет ли он быть затронутым другим телом. Например, для вы можете использовать это, чтобы избежать вычислений столкновений, которые бы приводили к незначительным изменениям скорости тела.

source.

Таким образом, результат зависит от того, как вы установили categoryBitMask на этих двух телах. Значение по умолчанию для categoryBitMask равно 0xFFFFFFFF, означает, что все биты установлены. Поэтому, когда вы выполняете & между 0xFFFFFFFF и 0b10 или 0b01, результатом будет отличное от нуля значение, таким образом, столкновение.

Так, например, устанавливая свои тела, как это:

spriteA.physicsBody?.categoryBitMask = 0b01 
spriteA.physicsBody?.collisionBitMask = 0b01 

и

spriteB.physicsBody?.categoryBitMask = 0b10 
spriteB.physicsBody?.collisionBitMask = 0b10 

даст вам результат, который вы хотите. Кроме того, это, вероятно, не точная настройка, которая вам нужна, это просто простой пример, и вам придется изменять значения в соответствии с вашими потребностями. В этом случае spriteA столкнется только с телами, у которых categoryBitMask установлено на 0b01. То же самое касается spriteB, он столкнется с телами, у которых categoryBitMask установлено на 0b10.

Кроме того, в случае, если вы не хотите, чтобы эти спрайты, чтобы иметь возможность столкнуться с чем-либо, просто установите их collisionBitMask свойства 0.

+0

Вау благодарит вас за подробный ответ! Решила мою проблему! –

2

Это не так, как вы проверить взаимодействие между узлами с соударений битами.

  • КатегорияBitMask - это категория объекта.
  • CollisionBitMask - это то, на что реагирует объект, когда столкнулся с ним.
  • ContactTestBitMask используется для уведомлений при пересечении для указанной битовой маски.

Предположим, у меня есть следующие:

struct PC { 
    static var player: UInt32 = 0b10 //2 
    static var enemy: UInt32 = 0b100 //4 
    static var rock: UInt32 = 0b1000 //8 
} 

player.physicsBody!.categoryBitMask = PC.player 
player.physicsBody!.collisionBitMask = PC.enemy | PC.rock 
enemy.physicsBody!.categoryBitMask = PC.enemy 
enemy.physicsBody!.collisionBitMask = PC.player 

Так что, когда вы проверяете, когда взаимодействие происходит в функции didBeginContact, проверить, если их взаимодействие происходит с помощью битную логики.

func didBeginContact(contact: SKPhysicsCountact) { 
    //1 
    let collision: UInt32 = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask 

    //2 
    if collision == PC.player | PC.enemy { 
     //An interaction occured between the player and enemy. 
    } 
  1. Переменные столкновения с использованием побитового OR, который |. В этом случае (если игрок касается врага), он получает категорию игрока (bodyA), которая равна 2, и получает категорию врага (bodyB), которая равна 4. Таким образом, 2 (0b10) OR 4 (0b100) равен 6 (0b110), которому присваивается столкновение.

  2. Итак, тогда в выражении if он проверяет, является ли столкновение 6 равным (PC.player | PC.enemy), что является истинным, поэтому взаимодействие между игроком и противником произошло, поскольку это было бы, если бы 6 == 6.

Вы можете использовать переменное столкновение для проверки любого взаимодействия. Например, в моей тестовой игре у меня есть следующая функция, которая проверяет, какие объекты коснулись.

func didBeginContact(contact: SKPhysicsContact) { 
    let collision: UInt32 = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask 

    //Collision between the penguin and land 
    if collision == PhysicsCategory.Land | PhysicsCategory.Animal { 
     lostLevel() 
    } else if collision == PhysicsCategory.Animal | PhysicsCategory.Pillow { 
     animalCounter -= 1 
     if animalCounter == 0 { 
      wonLevel() 
     } 
    } 
} 
+1

Большое вам спасибо за ваш ответ !! –

+0

Это подробное объяснение. Таким образом, бит-бит столкновения используется для идентификации коллизий системой, и это вызывает функцию didBeginContant, в которой categoryBitMask может использоваться для выделения того, какое столкновение произошло. – nnrales

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