2015-04-25 1 views
0

Я проверил ответ здесь и на других сайтах, но не получил окончательного решения.Почему сбой SpriteKit при переходе между сценами

У меня есть две сцены

Сцена 1:

class GameMenuScene: SKScene { 

override func didMoveToView(view: SKView) { 

    // Add background 
    var background: SKSpriteNode = SKSpriteNode(imageNamed: "Starfield") 
    background.position = CGPointMake(-20, 0) 
    background.size = CGSizeMake(self.size.width + 40, self.size.height) 
    background.anchorPoint = CGPointZero 
    background.blendMode = SKBlendMode.Replace 
    self.addChild(background) 

    // Add game title 
    gameTitle = SKSpriteNode(imageNamed: "Title") 
    gameTitle.name = "Game Title" 
    gameTitle.xScale = scale 
    gameTitle.yScale = scale 
    gameTitle.position = CGPoint(x: CGRectGetMidX(self.frame), y: self.frame.height * 0.75) 
    self.addChild(gameTitle) 

    // Add scoreboard 
    scoreboard = SKSpriteNode(imageNamed: "ScoreBoard") 
    scoreboard.name = "Scoreboard" 
    scoreboard.xScale = scale 
    scoreboard.yScale = scale 
    scoreboard.position = CGPoint(x: CGRectGetMidX(self.frame), y: self.frame.height * 0.50) 
    self.addChild(scoreboard) 

    // Add play button 
    playButton = SKSpriteNode(imageNamed: "PlayButton") 
    playButton.name = "PlayButton" 
    playButton.xScale = scale 
    playButton.yScale = scale 
    playButton.position = CGPoint(x: CGRectGetMidX(self.frame), y: self.frame.height * 0.25) 
    self.addChild(playButton) 

    // Add menu score label 
    var menuScoreLabel = SKLabelNode() 
    menuScoreLabel.fontName = fontName 
    menuScoreLabel.fontSize = scoreFontsize 
    menuScoreLabel.text = String(score) 
    menuScoreLabel.position = CGPointMake(scoreboard.position.x - (scoreboard.size.width/4), scoreboard.position.y - (scoreboard.size.height/4)) 
    menuScoreLabel.zPosition = 10 
    self.addChild(menuScoreLabel) 

    // Add menu top score label 
    var menuTopScoreLabel = SKLabelNode() 
    menuTopScoreLabel.fontName = fontName 
    menuTopScoreLabel.fontSize = scoreFontsize 
    menuTopScoreLabel.text = String(userDefaults.integerForKey("TopScore")) 
    menuTopScoreLabel.position = CGPointMake(scoreboard.position.x + (scoreboard.size.width/4), scoreboard.position.y - (scoreboard.size.height/4)) 
    menuTopScoreLabel.zPosition = 10 
    self.addChild(menuTopScoreLabel) 

} 

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) { 
    /* Called when a touch begins */ 

    for touch in (touches as! Set<UITouch>) { 

     // Get touch location 
     var touchLocation = touch.locationInNode(self) 

     // Check if Play button is presssed 

     if playButton.containsPoint(touchLocation) == true { 

      //println("right node touched") 

      // Transition to GameScene.swift 
      var transition: SKTransition = SKTransition.fadeWithDuration(1) 

      // Configure the view. 
      let scene = GameScene() 
      let skView = self.view! as SKView 
      skView.showsFPS = true 
      skView.showsNodeCount = true 

      /* Sprite Kit applies additional optimizations to improve rendering performance */ 
      skView.ignoresSiblingOrder = true 

      /* Set the scale mode to scale to fit the window */ 
      scene.size = skView.bounds.size 
      scene.scaleMode = .AspectFill 

      skView.presentScene(scene, transition: transition) 

     } 
    } 
} 

}

Сцена 2:

Класс GameScene: SKScene, SKPhysicsContactDelegate {

override func didMoveToView(view: SKView) { 
    /* Setup your scene here */ 

    // Add background 
    var background: SKSpriteNode = SKSpriteNode(imageNamed: "Starfield") 
    background.position = CGPointMake(-20, 0) 
    background.size = CGSizeMake(self.size.width + 40, self.size.height) 
    background.anchorPoint = CGPointZero 
    background.blendMode = SKBlendMode.Replace 
    self.addChild(background) 

    // Add mainlayer & labelHolderLayer 
    self.addChild(mainLayer) 
    self.addChild(labelHolderLayer) 

    // Add cannon 
    cannon = SKSpriteNode(imageNamed: "Cannon") 
    cannon.name = "Cannon" 
    cannon.position = CGPoint(x: CGRectGetMidX(self.frame), y: 0) 
    self.addChild(cannon) 

    // Add score label 
    scoreLabel.name = "Score Label" 
    scoreLabel.fontName = fontName 
    scoreLabel.fontSize = scoreFontsize 
    scoreLabel.text = String(score) 
    scoreLabel.position = CGPointMake(CGRectGetMidX(self.frame), self.frame.size.height - scoreFontsize) 
    scoreLabel.zPosition = 10 
    self.addChild(scoreLabel) 

    // Add LivesDisplay 
    livesDisplay = SKSpriteNode(imageNamed: "Ammo5") 
    livesDisplay.name = "livesDisplay" 
    livesDisplay.position = CGPoint(x: self.size.width - livesDisplay.size.width, y: self.size.height - livesDisplay.size.height) 
    self.addChild(livesDisplay) 

    // Settings for new game 
    newGame() 

} 

func gameIsOver() { 

    // Set game over flag and stop movement 
    gameOver = 1 
    mainLayer.speed = 0 
    mainLayer.paused = true 

    // Add game over label 
    gameOverLabel.fontName = fontName 
    gameOverLabel.fontSize = gameOverFontsize 
    gameOverLabel.text = "Game Over!" 
    gameOverLabel.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)) 
    gameOverLabel.zPosition = 10 
    labelHolderLayer.addChild(gameOverLabel) 

    // Set main menu top score 
    if score > userDefaults.integerForKey("TopScore") { 

     userDefaults.setInteger(score, forKey: "TopScore") 
     userDefaults.synchronize() 

    } 

    // Run acton sequence (wait a few seconds before transitioning) 
    runAction(SKAction.sequence([SKAction.waitForDuration(1), SKAction.runBlock({() -> Void in 

     // Transition back to GameMenuScene 
     var transition: SKTransition = SKTransition.fadeWithDuration(1) 

     // Configure the view. 
     let scene = GameMenuScene() 
     let skView = self.view! as SKView 
     skView.showsFPS = true 
     skView.showsNodeCount = true 

     /* Sprite Kit applies additional optimizations to improve rendering performance */ 
     skView.ignoresSiblingOrder = true 

     /* Set the scale mode to scale to fit the window */ 
     scene.size = skView.bounds.size 
     scene.scaleMode = .AspectFill 

     skView.presentScene(scene, transition: transition) 

    })])) 

} 

}

Когда я изначально запускаю приложение, я могу перейти от сцены 1 к сцене 2. Когда игра закончена, приложение переходит на сцену 1. НО, когда я снова попытаюсь перейти на сцену 2, приложение сбои. Это происходит только на устройстве, на симуляторе, я могу идти туда и обратно без проблем.

Ошибка, которую я получаю, заключается в добавлении SKNode, который уже существует. Я знаю, что это значит, и ошибка начинается, когда я пытаюсь

// Add mainlayer & labelHolderLayer 
    self.addChild(mainLayer) 
    self.addChild(labelHolderLayer) 

Но я не понимаю, почему это может добавить фон без проблем, но аварии оттуда. И почему он работает на симуляторе, но не на устройстве? действительно ли мне нужно проверить мой файл didMoveToView, если узлы уже созданы?

ответ

1

Я узнал, какую ошибку я делал.

Я создавал объекты за пределами моей сцены 2 класса, делая их глобальными. Поэтому, когда я вышел из сцены 1 -> сцена 2 -> сцена 1, не было проблем, но переход к сцене 2 снова вызвал сбой, потому что узлы были созданы глобально.

Решение:

Moving следующий код в классе решить эту проблему.

var mainLayer = SKSpriteNode() 
var labelHolderLayer = SKSpriteNode() 
var livesDisplay = SKSpriteNode() 
var scoreLabel = SKLabelNode() 

 Смежные вопросы

  • Нет связанных вопросов^_^