Что такое "категория маски" и "маска столкновения" от Sprite Kit?

Я следую руководству Sprite Kit, и в редакторе сцены он просит меня установить маску категории на 32 и маску столкновения на 11. Как связаны эти числа?

1 ответ

Решение

Битовая маска категории сообщает Sprite-Kit, что это за объект. Битовая маска Collision сообщает Sprite Kit, с какими объектами сталкивается этот объект (то есть ударит и отскочит). Битовая маска ContactTest сообщает Sprite-Kit, о каких контактах вы хотите получать уведомления, т.е. когда этот объект касается другого объекта.

Столкновения обрабатываются автоматически игровым движком Sprite-Kit; контакты обрабатываются вашим кодом - когда контакт, который вас интересует, ваш код (didBeginContact'для Swift 2,'didBegin(contact:) для Swift 3 и позже) называется.

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

Например, в вашей сцене у вас есть игрок, игрок-ракета, враг и край экрана. Предположим, что битовые маски 8-битные, а не 32-битные. Думайте о каждом числе как о диапазоне 8 двоичных цифр (8 битов), каждая из которых является 0 или 1.

Объекты в вашей сцене должны иметь уникальные категории, поэтому мы назначим их следующим образом:

player.categoryBitMask        = 00000001  (1 in decimal)
playerMissile.categoryBitMask = 00000010  (2 in decimal)
enemy.categoryBitMask         = 00000100  (4 in decimal)
screenEdge.categoryBitMask    = 00001000  (8 in decimal)

Если вы используете числа, которые в десятичном виде отличаются от степени 2 (1, 2, 4, 8, 16, 32, 64, 128 и т. Д.), То в битовой маске категории будет установлено более 1 бита, что усложнит вещи (это означает, что этот объект принадлежит к нескольким категориям), и ваш код должен быть более сложным.

Теперь подумайте о том, что отскакивает от чего (столкновения). Допустим, все отскакивает от всего остального, кроме ракеты проходит через край экрана.

Битовые маски коллизий для каждого объекта состоят из битов, которые представляют объекты, с которыми сталкивается этот объект, т.е.

player.collsionBitMask         = 00001111 (15 in decimal) (the bits for all other objects are set)
playerMissile.collisionBitMask = 00000111 (7) (all object EXCEPT screenEdge)
enemy.collisonBitMask          = 00001111 (15) (everything)
screenEdge.collisonBitMask     = 00000000 (0) (collides with nothing)

Теперь мы думаем о том, какие объектные взаимодействия нас интересуют. Мы хотим знать, когда:

  • касание игрока и врага
  • касание врага и игрока или касание врага и ракеты игрока.

Это представлено:

player.contactTestBitMask = 00000100 (4) (the enemy's categoryBitMask)
enemy.contractTestBitMask = 00000011 (3) (the player's categoryBitMask combined with the missile's categoryBitMask))

Обратите внимание, что если вы хотите знать, когда A и B касаются, достаточно просто указать contactTestBitMask (CTBM) для A, чтобы включить categoryBitMask от B; Вам не нужно устанавливать CTBM B в категорию A. Но если вы хотите, чтобы они отскакивали друг от друга, то каждый объект collisionBitMask должен включать в себя категорию CategoryBitMask другого объекта. Если collisonbitMask A включает в себя категорию B, но не наоборот, то, когда 2 сталкиваются, A отскочит, но B не изменится.

Для вашего конкретного примера (Категория Маска до 32 и Маска коллизии до 11) категория БитМаска равна 32, что 00100000 (придерживаясь только 8 бит). Значение collisionBitMask равно 11, то есть 8 + 4 + 1, поэтому в двоичном виде это "00001101", что означает, что он сталкивается с объектами с категорией CategoryBitMask 8, 4 или 1, поэтому я предполагаю, что в вашей сцене есть объекты с этими categoryBitMasks.

По умолчанию все отскакивает от всего остального, то есть collisionBitMask - это все "1", т.е. b'111111.. ", и ничто не уведомляет о контактах с чем-либо еще, т. Е. ContactTestBitMask - это все" 0 ".

Также - все это относится к физическим телам, а не к узлам.

Другие вопросы по тегам