2017-03-22 1 views
1

Ich versuche herauszufinden, wie die Erkennung von Kollisionen funktioniert, wenn Enums gesetzt werden. Ich habe mehrere verschiedene Knoten, auf denen ich Kollisionen erkennen kann und die funktionieren, aber ich habe sie einfach geflügelt und verstehe nicht, wie ich sie richtig einrichten soll.Schnelles Erkennen von Kollisionen und Setzen von Enums

enum ColliderType: UInt32{ 

    case ship = 1 
    case object = 2 
    case fuel = 4 
    case alien = 8 
    case torp = 16 

} 

Dann habe ich jeden Knoten als solche eingerichtet:

mete.physicsBody!.contactTestBitMask = ColliderType.object.rawValue 
mete.physicsBody!.categoryBitMask = ColliderType.object.rawValue 
mete.physicsBody!.collisionBitMask = ColliderType.object.rawValue 

alien.physicsBody!.contactTestBitMask = ColliderType.torp.rawValue 
alien.physicsBody!.categoryBitMask = ColliderType.alien.rawValue 
alien.physicsBody!.collisionBitMask = ColliderType.alien.rawValue 

fuel.physicsBody!.contactTestBitMask = ColliderType.ship.rawValue 
fuel.physicsBody!.categoryBitMask = ColliderType.fuel.rawValue 
fuel.physicsBody!.collisionBitMask = ColliderType.fuel.rawValue 


ship.physicsBody!.contactTestBitMask = ColliderType.object.rawValue 
ship.physicsBody!.categoryBitMask = ColliderType.ship.rawValue 
ship.physicsBody!.collisionBitMask = ColliderType.ship.rawValue 

torpedoNode.physicsBody!.contactTestBitMask = ColliderType.alien.rawValue 
torpedoNode.physicsBody!.categoryBitMask = ColliderType.torp.rawValue 
torpedoNode.physicsBody!.collisionBitMask = ColliderType.alien.rawValue 

Dann eine Kollision zwischen dem Schiff zu erkennen und zu einem mete der folgende Code ist das, was ich verwende:

if contact.bodyA.categoryBitMask == ColliderType.object.rawValue || contact.bodyB.categoryBitMask == ColliderType.object.rawValue 

Eine Kollision zwischen dem Schiff und Kraftstoff verwende ich:

if contact.bodyA.categoryBitMask == ColliderType.fuel.rawValue || contact.bodyB.categoryBitMask == ColliderType.fuel.rawValue { 

Dann endlich eine Kollision zwischen einem Torpedo und Alien Ich benutze diesen Code:

if contact.bodyA.categoryBitMask == ColliderType.alien.rawValue || contact.bodyB.categoryBitMask == ColliderType.torp.rawValue { 

Alles funktioniert perfekt aber ich bin jetzt versuchen, eine Kollision zwischen dem Schiff zu erkennen und zu fremd, und ich kann nicht arbeiten, wie es weiter zu gehen darüber zu tun. Ich muss versuchen, die Logik zu verstehen und diesen Code aufzuräumen.

+0

Was haben Sie als ‚ColliderType‘ ist nur eine Physik Kategorie. Das Festlegen einer Kategorie für die Kollision von Objekten mit dem Objekt collisionBitMask und contactTestBitMask ist nicht wirklich sinnvoll. –

+0

Es gibt viele Antworten hier auf SO, die erklären, woran Sie interessiert sind: http://StackOverflow.com/A/39064710, http://StackOverflow.com/A/31111039 etc ... – Whirlwind

+1

Zuerst kommen Sie mit Ihrem Kopf herum der Unterschied zwischen ** Kontakte ** und ** Kollisionen ** und starten Sie mit der richtigen Terminologie - Sie erkennen keine Kollisionen, Sie erkennen * Kontakte * .- http://StackOverflow.com/documentation/sprite-Kit/6261/sknode-collision/29294/Differenz-zwischen-Kontakten-und-Kollisionen # t = 201703220900020381008 –

Antwort

2

Wenn Sie Ihr Code benachrichtigt werden möchten, wenn Schiff Kontakte (nicht kollidiert) entweder ein misst, Kraftstoff oder ein Ausländer, sollten Sie haben:

ship.physicsBody!.contactTestBitMask = ColliderType.object.rawValue | ColliderType.fuel.rawValue | ColliderType.alien.rawValue 

dh die Kontakt Test-Bit-Maske ist gleich object OR fuel ODER alien.

Sehen Sie sich dieses einfache Sprite-Kit-Projekt hier auf SO mit Kontakten, Kollisionen, Berührungsereignissen und einer Hilfsfunktion an (checkPhysics()), die Ihr Physik-Setup analysieren wird - diese Funktion kann in jedes Sprite-Kit-Projekt eingefügt und aufgerufen werden Zeigen Sie, welche Kontakte und Kollisionen zwischen welchen Physikkörpern auftreten werden.

Attack button in SpriteKit

Zusätzliche Informationen:

Es ist daran zu erinnern, dass, wenn Sie nichts anderes angeben, alles kollidiert mit alles andere und allem nichts Kontakten.

d.h. jeder collisonBitMask des Knotens wird auf all 1 s eingestellt und seine contactTestbitMask all 0 s eingestellt ist. ausschalten

nodeA.physicsBody?.collisionBitMask &= ~nodeB.category 

Wir logisch UND nodeA der Bitmaske mit dem inversen (logische NOT, der Operator ~) von nodeB der Kategorie Bitmaske‘:

Kontakte oder Kollisionen zwischen nodeA und nodeB kann off mit gedreht werden 'das Bit nodeA's bitMask.

Kontakte oder Kollisionen zwischen nodeA und nodeC kann mit ON an einer beliebigen Stelle gedreht werden:

nodeA.physicsBody?.contactTestBitMask |= nodeC.category 

Wir logisch UND nodeA der Bitmaske mit nodeC der Kategorie Bitmaske zu ‚schalten‘, dass etwas in nodeA der Bitmaske.

können Sie sicherstellen, dass jede Form ‚abprallt‘ eine Bildschirmrand wie folgt:

// Make sure everything collides with the screen edge 
enumerateChildNodes(withName: "//*") { node, _ in 
    node.physicsBody?.collisionBitMask |= self.edgeCategory //Add edgeCategory to the collision bit mask 
} 
+0

Ich habe ColliderType.alien.rawValue zur Kontaktmaske für Schiffe hinzugefügt. Würde ich dann verwenden, wenn contact.bodyA.categoryBitMask == ColliderType.alien.rawValue || contact.bodyB.categoryBitMask == ColliderType.alien.rawValue {? Ich habe ein paar Kombinationen ausprobiert, aber es bringt normalerweise andere Kontakte durcheinander. –

+0

@Alex - Ja, aber wenn Sie all diese 'if..then' und die bodyA- und bodyB-Dinge vermeiden wollen, schauen Sie sich das an, um didBegin (contact :) - http://stackoverflow.com/ zu implementieren. Dokumentation/Sprite-Kit/6261/Sknode-Kollision/24159/alternative-didbegincontact # t = 201703221158558453557 –