2016-04-21 12 views
1

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?

+0

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

+0

wenn ich den folgenden Kommentar aus: if (! CollidedBallNode = nil) {// gotoGameOverScene (! CollidedBallNode) } Das Spiel nicht – user594883

+0

Vielleicht nicht zum Absturz zu erwähnen, dass ich in Simulator nicht auf dem Gerät laufen lasse. – user594883

Antwort

0

Ahhh ... Ich habe es. Dummes Stück Code bei removeLightNode-Funktion. Dies führte zu entfernen nicht nach der Kollision zu arbeiten: while(nodeToRemove != nil && endOfSceneCollision == false)