2016-08-21 4 views
11

Próbuję użyć masek bitowych masek bitowych kolizji i testów kontakt Swift, chcę dwa obiekty nie zderzają się ze sobą, tak robię:nie mogę zrozumieć, jak działa zderzenie bit maski

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

Rejestracja SpriteKit wykonuje operację AND na tych dwóch liczbach, czy wynik nie powinien być 00 od 10 & 01 = 00?

Dlaczego więc zdarza się kolizja?

Dziękuję.

Odpowiedz

7

Tak nie działa obsługa kolizji. Jeżeli dwa korpusy są przecięcia silnik fizyczny wykonuje logiczny AND operatora pomiędzy ciałem collisionBitMask i nawzajem ciała Current categoryBitMask:

gdy dwie jednostki Physics stykają się ze sobą, może dojść do kolizji. Maska kolizyjna tego ciała jest porównywana z maską innego obiektu o nazwie , wykonując operację logiczną AND. Jeśli wynik jest niezerową wartością, to kolizja ma wpływ na tę bryłę. Każdy organ niezależnie wybiera, czy chce być dotknięty przez inne ciało. W przypadku przykładu można tego użyć, aby uniknąć obliczeń kolizji, które spowodowałyby nieznaczne zmiany prędkości ciała.

The source.

Tak więc wynik zależy od tego, jak ustawić categoryBitMask na tych dwóch ciałach. Domyślna wartość dla categoryBitMask to 0xFFFFFFFF, oznacza wszystkie ustawione bity. Więc jeśli wykonasz & pomiędzy 0xFFFFFFFF i 0b10 lub 0b01, wynik będzie niezerowy, a więc kolizja.

Tak na przykład, ustawienie ciała swoje tak:

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

i

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

daje wynik chcesz. Ponadto, prawdopodobnie nie jest to dokładna konfiguracja, której potrzebujesz, to tylko prosty przykład, i będziesz musiał zmienić wartości w zależności od potrzeb. W takim przypadku spriteA zderzy się tylko z obiektami, które mają categoryBitMask ustawione na 0b01. To samo dotyczy spriteB, zderzy się z ciałami, które mają categoryBitMask ustawione na 0b10.

Również w przypadku, gdy nie chcesz te skrzaty, aby móc zderzają się z niczego, po prostu ustawić swoje collisionBitMask właściwości 0.

+0

Dziękuję za tę szczegółową odpowiedź! Rozwiązałem mój problem! –

2

To nie jest jak testować interakcje między węzłami z bitami kolizji.

  • KategoriaBitMask jest kategorią obiektu.
  • KolizjaBitMask jest tym, na co reaguje obiekt po zderzeniu.
  • Funkcja contactTestBitMask służy do powiadamiania o wystąpieniu przecięcia dla określonej maski bitowej.

Załóżmy, że mam następujące:

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 

Więc kiedy sprawdzają gdy zachodzi interakcja w funkcji didBeginContact, sprawdzając, czy ich oddziaływanie nastąpiło za pomocą bitowego logiki.

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. Zmienna kolizji korzysta logiczną OR, który jest |. W tym przypadku (jeśli gracz dotknie wroga), otrzymuje kategorię gracza (bodyA), która wynosi 2, i otrzymuje kategorię wroga (bodyB), która wynosi 4. So 2 (0b10) OR 4 (0b100) jest równy 6 (0b110), który jest przypisany do kolizji.

  2. Więc w if sprawdza, czy kolizja z 6 jest równa (PC.player | PC.enemy), co jest prawdą, a zatem oddziaływanie miało miejsce między odtwarzaczem a wrogiem ponieważ byłoby gdyby 6 == 6.

Możesz użyć kolizji zmiennej do przetestowania dowolnej interakcji. Na przykład w mojej grze testowej mam następującą funkcję, która testuje, jakie przedmioty zostały dotknięte.

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

Dziękuję bardzo za odpowiedź !! –

+0

To jest szczegółowe wyjaśnienie. Tak więc maski bitów kolizyjnych są używane do identyfikacji kolizji przez system, a to uruchamia funcję didBeginContant, w ramach której właściwość categoryBitMask może być używana do wyodrębnienia kolizji. – nnrales

Powiązane problemy