2016-04-21 58 views
1

我正在嘗試爲我的孩子創建一個簡單的遊戲。我正在嘗試實現光源和發射器節點。然而遊戲在碰撞時崩潰,這應該導致gameOverScene。奇怪的是,如果我添加一個剎車點,代碼就完成了。下面的代碼:Spritekit遊戲崩潰(因爲SKLightNode線程問題?)

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") 
     }) 
    } 

並且它導致這樣:

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 

,但如果我把斷點調試器下面的行之前:

print("step 1") 

代碼成功地執行。必須是線程/同步問題,但這比Spritekit/Swift更勝過我的技術。有人可以幫我解決這個問題嗎?

+0

所以你說如果你從代碼中完全移除gotoGameOverScene(collidedBallNode!),你的遊戲就不會崩潰(不管你做什麼,例如,在屏幕上輕敲等)?你對此有絕對的肯定嗎? – Whirlwind

+0

如果我註釋掉以下內容:if(collidedBallNode!= nil){gotoGameOverScene(collidedBallNode!) }遊戲不會崩潰 – user594883

+0

也許值得一提的是,我在模擬器中運行而不是設備上。 – user594883

回答

0

啊......我明白了。 removeLightNode函數中一段愚蠢的代碼。這導致在碰撞後移除不工作:while(nodeToRemove != nil && endOfSceneCollision == false)