Manchmal werden in meinen SpriteKit-Programmen meine Kollisionen und Kontakte (unter Verwendung von SKPhysicsBody) nicht wie erwartet ausgelöst oder funktionieren. Ich denke, ich habe alles eingerichtet, was ich brauche, aber ich bekomme immer noch nicht die richtigen Interaktionen. Wie kann ich leicht überprüfen, was mit was kollidiert und welche Körper aufgebaut sind, um Kontakte zu generieren?iOS SpriteKit - Kollisionen und Kontakte funktionieren nicht wie erwartet
Antwort
Um diese Art von Problemen zu diagnostizieren, habe ich eine Funktion geschrieben, die von überall aufgerufen werden kann und die aktuelle Szene analysiert und eine Liste der Knoten mit Kollision mit anderen Kollisionen und Kollisionen meiner Szene erstellt zum.
Die Funktion ist Stand-alone und muss nicht über die Knoten in der Szene informiert werden.
Die Funktion ist wie folgt:
//MARK: - Analyse the collision/contact set up.
func checkPhysics() {
// Create an array of all the nodes with physicsBodies
var physicsNodes = [SKNode]()
//Get all physics bodies
enumerateChildNodesWithName("//.") { node, _ in
if let _ = node.physicsBody {
physicsNodes.append(node)
} else {
print("\(node.name) does not have a physics body so cannot collide or be involved in contacts.")
}
}
//For each node, check it's category against every other node's collion and contctTest bit mask
for node in physicsNodes {
let category = node.physicsBody!.categoryBitMask
// Identify the node by its category if the name is blank
let name = node.name != nil ? node.name : "Category \(category)"
let collisionMask = node.physicsBody!.collisionBitMask
let contactMask = node.physicsBody!.contactTestBitMask
// If all bits of the collisonmask set, just say it collides with everything.
if collisionMask == UInt32.max {
print("\(name) collides with everything")
}
for otherNode in physicsNodes {
if (node != otherNode) && (node.physicsBody?.dynamic == true) {
let otherCategory = otherNode.physicsBody!.categoryBitMask
// Identify the node by its category if the name is blank
let otherName = otherNode.name != nil ? otherNode.name : "Category \(otherCategory)"
// If the collisonmask and category match, they will collide
if ((collisionMask & otherCategory) != 0) && (collisionMask != UInt32.max) {
print("\(name) collides with \(otherName)")
}
// If the contactMAsk and category match, they will contact
if (contactMask & otherCategory) != 0 {print("\(name) notifies when contacting \(otherName)")}
}
}
}
}
Sie müssen auch diese 3 Dinge überprüfen:
- die Szene muss ein
SKPhysicsContactDelegate
- sein Sie setzen müssen
physicsWorld.contactDelegate = self
- Sie müssen eine der optionalen Methoden implementieren:
didBeginContact
didEndcontact
Die Funktion aufgerufen werden soll, wenn Sie alle Ihre Bilder eingerichtet haben - in der Regel am Ende der didMoveToView
Werke:
checkPhysics()
Als ich Rufen Sie diese Funktion am Ende meiner didMoveToView
in meiner Praxis Swift-Projekt, bekomme ich folgende Ausgabe:
Optional ("shape_blueSquare") kollidiert mit Optional ("Kategorie 2147483648") Optional ("shape_blueSquare") kollidiert mit Optional ("shape_redCircle") Optional ("shape_blueSquare") kollidiert mit Optional ("shape_purpleSquare" Optional) ("shape_blueSquare") kollidiert mit Optional ("shape_yellowTriangle") Optional ("shape_redCircle") kollidiert mit Optional ("Kategorie 2147483648") Optional ("shape_redCircle") kollidiert mit Optional ("shape_blueSquare") Optional ("shape_redCircle") benachrichtigt bei der Kontaktaufnahme Optional ("shape_purpleSquare") Optional ("shape_redCircle") kollidiert mit Option al ("shape_yellowTriangle") Optional ("shape_redCircle") benachrichtigt, wenn Optional kontaktieren ("shape_yellowTriangle") Optional ("shape_purpleSquare") kollidiert mit Optional ("Kategorie 2147483648") Optional ("shape_purpleSquare") kollidiert mit Optional ("shape_yellowTriangle") Optional ("shape_yellowTriangle") kollidiert mit allem, was didBeginContact eingegeben für Optional ("shape_purpleSquare") und optional ("shape_redCircle") didBeginContact eingetragen für Optional ("shape_purpleSquare") und Optional ("shape_redCircle") didBeginContact eingegeben für Optional ("shape_yellowTriangle") und Optional ("shape_redCircle")
Kategorie 2147483648 ist meine Kantengrenze und hat keinen Namen. Ich gab ihm diese Kategorie, um seine Kollision zu entsprechenBitMask
Bitte fühlen Sie sich frei, diese Funktion zu versuchen und lassen Sie mich wissen, wenn es nützlich ist oder wenn es irgendwelche Situationen gibt, die es nicht behandelt.
Dies ist ein github wertvolles Werkzeug! – Confused
Diese Art von Fragen sind tatsächlich geeignet für [Code Review] (http://codereview.stackexchange.com/) – Whirlwind
Dies ist nur für Code Review geeignet, wenn der Code wie erwartet funktioniert und wenn das OP eine Überprüfung möchte. .. Vom Ton dieser Frage will er keine Überprüfung, er will eine Fehlerüberprüfung seines Codes ... –
Eigentlich möchte ich nicht, dass mein Code überprüft wird, da ich denke, dass es funktioniert, aber ich habe versucht, etwas zu schreiben, das Leuten mit Kollisions-/Kontaktproblemen helfen würde. Vielleicht hätte ich eine Frage stellen sollen, dass ich Probleme habe und dann meine CheckPhysik als Antwort funktioniert? –