2016-02-02 9 views
1

Я использую SpriteKit и Swift 2. Я знаю, что есть много учебников, но я чувствую, что они устарели или я схожу с ума, потому что кажется, что у всех есть другое мнение о том, что делают разные маски физики.Объекты, сталкивающиеся друг с другом, когда они не должны (SpriteKit)

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

var everythingElseCategory: UInt32 = 3 
var object1Category: UInt32 = 2 
var object2Category: UInt32 = 4 

object1.physicsBody?.categoryBitMask = object1; 
object1.physicsBody?.collisionBitMask = everythingElseCategory 

object2.physicsBody?.categoryBitMask = object2; 
object2.physicsBody?.collisionBitMask = everythingElseCategory 

everythingElse.physicsBody?.categoryBitMask = everythingElseCategory; 
everythingElse.physicsBody?.collisionBitMask = 0 //its a wall 

я должен иметь концепцию битовых масок перепутались, потому что для меня столкновение битовой маски является то, что он сталкивается с, но я, кажется, должен быть неправильным, потому что это решение не работает , Object2 сталкивается с object1, но object1 не сталкивается с object2 !!!?! ??!

Любые идеи относительно того, что я делаю неправильно?

Спасибо!

+0

Ключ -> те битовые маски, чтобы избежать нежелательного поведения, что лучше назначать их таким образом UInt32 = 0x1 << 0. – ColdSteel

+1

[Пример физики Apple SpriteKit] (https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/SpriteKit_PG/Physics/Physics.html#//apple_ref/ doc/uid/TP40013043-CH6-SW15) также может представлять интерес. Вы используете целочисленные значения, где вам нужно использовать двоичный файл. Преобразуя их, ваша категория столкновения - '0011', где ваша' object2Category' '0100', что означает, что она не столкнется. Самый простой способ сделать это - использовать бит-сдвиг для создания бит-масок. – Gliderman

+0

Посмотрите на эту статью в Википедии, чтобы лучше понять, как работают битмаски. Https://en.wikipedia.org/wiki/Mask_(computing) – Knight0fDragon

ответ

2

Перемещение этого с моего комментария.

Apple's SpriteKit physics example может представлять интерес.

Вы используете целочисленные значения, а не двоичные значения. Вот то, что ваши ценности выглядят как в двоичной системе:

everythingElseCategory = 0011b // I think you need the "b" somewhere to indicate binary 
object1Category = 0010b 
object2Category = 0100b 

В основном, физика SK будет использовать & (двоичный и) оператора на двух объектах, и если значение не 0, они будут сталкиваться. Возьмем, например, ваши два объекта:

object1.physicsBody?.categoryBitMask = object1 (0010) 
object1.physicsBody?.collisionBitMask = everythingElseCategory (0011) 

object2.physicsBody?.categoryBitMask = object2 (0100) 
object2.physicsBody?.collisionBitMask = everythingElseCategory (0011) 

object1 «s битовая маска будет сталкиваться с object2» потому, что 0010 & 0011 == 0010 или отличными от нуля. 's бит-маска не будет сталкиваться с object1, потому что 0100 & 0011 == 0000 столкновение с нулем или без него.

Самый простой способ исправить это - использовать сдвиг бит. Синтаксис выглядит следующим образом:

value = bitValue << placesToShiftLeft 

Так что ваша бита настройка маски будет выглядеть следующим образом:

everythingElseCategory = 1 << 0 // I have this shifted by 0 just to show that you can do that 
object1Category = 1 << 1 
object2Category = 1 << 2 

Теперь, когда вы установите битые маски для ваших объектов, используйте | (двоичный или) оператору объединить их. 001 | 010 == 011 как это работает.

object1.physicsBody?.categoryBitMask = object1Category 
object1.physicsBody?.collisionBitMask = everythingElseCategory | object2Category 

object2.physicsBody?.categoryBitMask = object2Category 
object2.physicsBody?.collisionBitMask = everythingElseCategory | object1Category 

everythingElse.physicsBody?.categoryBitMask = everythingElseCategory | object1Category | object2Category 

Это позволит предотвратить множественные object1 «s из сталкивающихся друг с другом, но и позволяют сталкиваясь со всем остальным.

1

Другой способ кодирования битовой маски столкновения - запомнить, что по умолчанию он установлен в UInt32.max, то есть все сталкивается со всем. Если вы хотите, чтобы тело столкнулось со всем, кроме определенных тел, легче начать с того, что он сталкивается со всем, а затем выключить биты, представляющие объекты, которые вы не вызывали, .

// Assign the category 
object1.physicsBody?.categoryBitMask = object1Category 
    // Turn off collisions with object1 and object2 
object1.physicsBody?.collisionBitMask &= ~(object1Category | object2Category) 

Вы можете включать и выключать столкновений с конкретными категориями, не затрагивая другие коллизии следующим образом:

// Turn on collisions with object3 
object1.physicsBody?.collisionBitMask |= object3Category 

    // Turn off collisions with object4 
object1.physicsBody?.collisionBitMask &= ~object4Category 

    // Turn on collisions with object 5 & 6 
object1.physicsBody?.collisionBitMask |= (object5Category | object6Category) 
Смежные вопросы