在SpriteKit和Swift中解雇SKScene

时间:2014-12-22 15:29:36

标签: ios swift sprite-kit skscene

当我的游戏暂停时,我设法打开另一个信息/信用/设置视图

let block = SKAction.runBlock {
    let myScene = CreditsScene(size: self.size)
    myScene.scaleMode = self.scaleMode
    self.view?.presentScene(myScene)
}
self.runAction(block)

CreditsScene打开时,我可以点按场景返回暂停的游戏。 但无论我如何尝试,我都无法回去:(

目前我所做的最好就像是

let block = SKAction.runBlock {
    let myScene = GameScene(size: self.size)
    myScene.scaleMode = self.scaleMode
    self.view?.presentScene(myScene)
}
self.runAction(block)

在我看来,它开启了一个新的GameScene而不是之前的GameScene。我还尝试了removeFromParentpresentScene(nil),但都没有效果。

你还有其他更好的想法吗? 感谢

1 个答案:

答案 0 :(得分:4)

您正在展示新的GameScene,因为您正在创建新的GameScene。如果你想保留你正在使用的GameScene实例并返回它,你需要提供它。要么是这样,要么你需要一种方法让你的GameScene类保存和恢复它的状态,这样就可以恢复它的新实例来复制旧实例中发生的任何事情。


对于第一个选项,您可以执行以下操作:

// in GameScene
let block = SKAction.runBlock {
    let credits = CreditsScene(size: self.size)
    credits.returnToScene = self    // add this property to CreditsScene
    credits.scaleMode = self.scaleMode
    self.view?.presentScene(credits)
}
self.runAction(block)

// in CreditsScene
let block = SKAction.runBlock {
    self.view?.presentScene(self.returnToScene)
}
self.runAction(block)

在这里,您将对GameScene的当前CreditsScene的引用传递给CreditsScene,以便GameScene在完成后知道要返回的GameScene。或者,您可以在某个地方存储对当前GameScene的引用(至少相对于场景),如视图控制器。


对于另一个选项,您需要确保NSCoding类中的所有状态(或至少是对玩家有意义的所有状态)都可以保存和恢复:当前得分,当前玩家位置,敌人在哪里以及他们在做什么等等......无论你的游戏做什么。 SpriteKit类已经支持GameScene,所以这是处理保存/恢复的好方法 - 只需确保你的任何自定义子类(如GameScene)编码它们所拥有的状态。

然后,您可以在转移时归档// in GameScene let block = SKAction.runBlock { let credits = CreditsScene(size: self.size) credits.returnToScene = self // add this property to CreditsScene credits.scaleMode = self.scaleMode let sceneData = NSKeyedArchiver.archivedDataWithRootObject(self) sceneData.writeToFile(savedGamePath, atomically: true) self.view?.presentScene(credits) } self.runAction(block) // in CreditsScene let block = SKAction.runBlock { if let game = NSKeyedUnarchiver.unarchiveObjectWithFile(savedGamePath) { self.view?.presentScene(game) } } self.runAction(block) ,并在准备好返回时从该归档中恢复。这看起来像这样:

savedGamePath

(这假设SKAction.runBlock是两个类都可以访问的常量。)


顺便说一下,如果你在这里使用runBlock反映了游戏中的实际内容(而不是为了解决这个问题而简化你的代码),这是多余的。您不需要为即将运行的代码创建// in GameScene let credits = CreditsScene(size: self.size) credits.returnToScene = self // add this property to CreditsScene credits.scaleMode = self.scaleMode self.view?.presentScene(credits) // in CreditsScene self.view?.presentScene(self.returnToScene) 操作。因此,除非您确实需要将该操作存储起来以便以后运行,否则您可以将上面的第一个解决方案简化为以下内容:

{{1}}