Ich versuche, ein einfaches Spiel für meine Kinder zu erstellen. Ich versuche, Licht- und Emitterknoten zu implementieren. Allerdings stürzt das Spiel bei einer Kollision ab, was zu gameOverScene führen sollte. Das Seltsame ist, dass der Code in Ordnung ist, wenn ich einen Haltepunkt hinzufüge. Hier ist der Code:Spritekit Spiel stürzt ab (wegen SKLightNode Threading-Problem?)
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
touch = touches.first!
turnOnLightNode(touch.locationInNode(self))
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
touch = touches.first!
turnOnLightNode(touch.locationInNode(self))
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
removeLightNode()
}
func removeLightNode(){
var nodeToRemove = self.childNodeWithName("light")
while(nodeToRemove != nil && endOfSceneCollision == false) {
nodeToRemove?.removeFromParent()
nodeToRemove = self.childNodeWithName("light")
}
nodeToRemove = self.childNodeWithName("touchEmitterNode")
while(nodeToRemove != nil && endOfSceneCollision == false) {
nodeToRemove?.removeFromParent()
nodeToRemove = self.childNodeWithName("touchEmitterNode")
}
}
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
removeLightNode()
}
func turnOnLightNode(point: CGPoint){
removeLightNode()
light.name = "light"
light.categoryBitMask = 3
light.position = point
light.zPosition = 19.0
light.falloff = 0.5
light.enabled = true
light.lightColor = UIColor(red: 161/255, green: 218/255, blue: 237/255, alpha: 0.5)
light.shadowColor = UIColor(red: 161/255, green: 218/255, blue: 237/255, alpha: 0.5)
light.ambientColor = UIColor(red: 220/255, green: 220/255, blue: 220/255, alpha: 0.3)
addChild(light)
touchEmitter!.name = "touchEmitterNode"
touchEmitter!.position = point
touchEmitter!.zPosition = 100//gameFieldParticlesZPosition
addChild(touchEmitter!)
}
func didBeginContact(contact: SKPhysicsContact) {
var ballBody: SKPhysicsBody?
var lineBody: SKPhysicsBody?
var collidedBallNode: SKSpriteNode?
if contact.bodyA.categoryBitMask == 2 && contact.bodyB.categoryBitMask == 1 {
print("didBeginContactAB")
lineBody = contact.bodyA
ballBody = contact.bodyB
collidedBallNode = contact.bodyB.node as? SKSpriteNode
}
if contact.bodyA.categoryBitMask == 1 && contact.bodyB.categoryBitMask == 2 {
print("didBeginContactBA")
lineBody = contact.bodyB
ballBody = contact.bodyA
collidedBallNode = contact.bodyA.node as? SKSpriteNode
}
if contact.bodyA.categoryBitMask == 1 && contact.bodyB.categoryBitMask == 4 {
//audioController.playSound(electricBounceSound, volume: 1.0)
}
if contact.bodyA.categoryBitMask == 4 && contact.bodyB.categoryBitMask == 1 {
//audioController.playSound(electricBounceSound, volume: 1.0)
}
if contact.bodyA.categoryBitMask == 1 && contact.bodyB.categoryBitMask == 1 {
//audioController.playSound(electricNoiseSound, volume: 1.0)
}
if(collidedBallNode != nil){
gotoGameOverScene(collidedBallNode!)
}
}
func gotoGameOverScene(explodingBallNode: SKSpriteNode){
print("step 1") //IF BREAKPOINT HERE, ALL EXECUTES OK
self.runAction(SKAction.waitForDuration(2.5), completion: {
print("step 2")
let gameOverScene = GameOverScene(size: self.size)
print("step 3")
self.view?.presentScene(gameOverScene, transition: reveal)
print("step 4")
})
}
Und es führt dazu:
didBeginContactAB
step 1
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attemped to add a SKNode which already has a parent: <SKLightNode> name:'light' position:{296.99994, 191.49995} scale:{1.00, 1.00} accumulatedFrame:{{297, 191.5}, {0, 0}}'
*** First throw call stack:
(
0 CoreFoundation 0x01384a14 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x00b5de02 objc_exception_throw + 50
2 CoreFoundation 0x0138493d +[NSException raise:format:] + 141
aber wenn ich Debugger-Breakpoint setzen, bevor die folgende Zeile ein:
print("step 1")
-Code ausführt erfolgreich. Muss ein Thread/Synchronisationsproblem sein, aber das ist mein Knowhow über Spritekit/Swift. Könnte mir jemand helfen, das zu beheben?
Also Sie sagen, dass wenn Sie 'gotoGameOverScene (collidedBallNode!)' Aus Ihrem Code vollständig entfernen, Ihr Spiel funktioniert ohne diesen Absturz (alles funktioniert, egal was Sie tun, z. Tippen auf Bildschirm usw.)? Bist du absolut optimistisch? – Whirlwind
wenn ich den folgenden Kommentar aus: if (! CollidedBallNode = nil) {// gotoGameOverScene (! CollidedBallNode) } Das Spiel nicht – user594883
Vielleicht nicht zum Absturz zu erwähnen, dass ich in Simulator nicht auf dem Gerät laufen lasse. – user594883