Versuchen Sie, die Web-und Stackoverflow, bevor er fragte eine Frage gerade weil es eine Menge von Tutorials im Internet und sogar Stack-Überlauf darüber. Diese Frage könnte sogar geschlossen werden, weil die Kollisionserkennung eine der Grundlagen in SpriteKit ist und viel über SO gefragt wurde.
Wie auch immer, es gibt einige Fehler/Auslassungen in Ihrem Code, also schauen wir es uns an.
1) Sie müssen den physics world contact delegate in Ihrer Szenen-Methode "didMoveToView" einstellen, so dass er tatsächlich nach Kontakten lauscht. Dies ist die Nummer 1, die Menschen, einschließlich mir, vergessen und sich stundenlang fragen, warum nichts funktioniert.
physicsWorld.contactDelegate = self
2) Sie sind nicht auch Ihre Sprites ein physicsBody geben
object.physicsBody = SKPhysicsBody(...)
Sie müssen sie immer einen Physik Körper geben erste und als Satz Eigenschaften wie contactTestBitMasks usw.
3) Versuchen Sie es mit? Anstatt von ! im Umgang mit Optionals, um Null-Abstürze zu vermeiden. Versuche das immer zu tun, obwohl du weißt, dass es nicht gleich Null ist. So sagen
...physicsBody?.contactTestBitMask...
statt
...physicsBody!.contactTestBitMask...
Sie manchmal tun es, und manchmal nicht.
In Ihrem aktuellen Code könnten Sie einen Absturz bekommen, weil das Objekt keinen physicsBody hat, aber Sie sind gezwungen, es auszupacken, im Wesentlichen zu sagen, dass es einen Physikkörper hat, der gefährlich ist.
Zum Beispiel im Code diese Zeile sollte
object.physicsBody?.applyImpulse(push)
nicht funktionieren, da es keine Physik Körper auf dem Objekt ist, sondern weil es nicht zwingen wird Abwickeln (?) Nichts passiert. Versuchen Sie, diese Zeile mit a zu ändern! und du solltest einen Crash bekommen. Also immer benutzen? im Umgang mit Optionals und wenn der Compiler das auch zulässt.
Auch diese Zeile sollte sein, nachdem Sie das Objekt Sprite nicht zuvor eingerichtet haben.
4) Versuchen Sie, Ihre Physik Kategorien anders zu schreiben, Ihr Weg wird sehr schnell verwirrend, wenn Sie weitere Kategorien hinzufügen, weil Sie nicht nur die letzte Zahl erhöhen können. In Ihrem Beispiel muss der nächste Collider-Typ also 4, 8, 16 usw. sein.
Versuchen Sie dies stattdessen, wo Sie nur die letzte Zahl um 1 erhöhen müssen.
struct ColliderType {
static let object: UInt32 = 0x1 << 0
static let boundary: UInt32 = 0x1 << 1
....
}
als es verwenden, wie so
...contactTestBitMask = ColliderType.object
...
Sie sollten ganze Code so aussehen
struct ColliderType {
static let object: UInt32 = 0x1 << 0
static let boundary: UInt32 = 0x1 << 1
}
class GameScene: SKScene, SKPhysicsContactDelegate {
var gameOver = false
var object: SKSpriteNode!
override func didMoveToView(view: SKView) {
scene?.scaleMode = SKSceneScaleMode.AspectFill
self.physicsWorld.gravity = CGVectorMake(0.0, 2.0)
physicsWorld.contactDelegate = self
object = SKSpriteNode(imageNamed: "Spaceship")
object.zPosition = 2
object.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
object.physicsBody = SKPhysicsBody(circleOfRadius: object.size.width/0.32)
object.physicsBody?.dynamic = true
object.physicsBody?.allowsRotation = true
object.physicsBody?.categoryBitMask = ColliderType.object
object.physicsBody?.contactTestBitMask = ColliderType.boundary
object.physicsBody?.collisionBitMask = ColliderType.boundary
self.addChild(object)
let boundary = SKPhysicsBody(edgeLoopFromRect: CGRect(x: 253, y: 138, width:515, height:354))
self.physicsBody = boundary
self.physicsBody?.friction = 0
boundary.contactTestBitMask = ColliderType.object
boundary.categoryBitMask = ColliderType.boundary
boundary.collisionBitMask = ColliderType.object
let push = CGVectorMake(10, 10)
object.physicsBody?.applyImpulse(push)
}
func didBeginContact(contact:SKPhysicsContact) {
print("We have Contact")
gameOver = true
self.speed = 0
}
}
this helps
Sie haben einen winzigen Fehler ... Um eine Szene zum Abhören des Kontakts zu machen, setzen Sie den Delegaten innerhalb einer Szene, nicht innerhalb eines 'viewDidLoad', das Mitglied eines View-Controllers ist. – Whirlwind
Ja, tut mir leid, ich sollte DidMoveToView sagen. Wird meine Antwort aktualisieren. Danke – crashoverride777
Hallo, zuerst einmal vielen Dank für Ihre ausführliche Antwort! Ich wollte erwähnen, dass ich einen physikalischen Körper hatte, der für mein Objekt eingerichtet war und der Befehl zum Delegieren des Kontakts bereits eingegeben wurde, also wollte ich mich entschuldigen, weil ich völlig vergessen hatte, diesen Code zum Zeitpunkt des Schreibens der ursprünglichen Frage hinzuzufügen. Mit meinem aktuellen Code kann das Objekt die inneren Kanten der Balken gut berühren und ist zwischen ihnen enthalten, aber ich bekomme keine Benachrichtigung darüber, dass ich Kontakt hergestellt habe. – Seed12