Я проверил ответ здесь и на других сайтах, но не получил окончательного решения.Почему сбой 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, если узлы уже созданы?