繁体   English   中英

在SpriteKit和Swift中关闭SKScene

[英]dismiss SKScene in SpriteKit and Swift

当我的游戏暂停时,我设法打开另一个视图以获取信息/积分/设置,如下所示:

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,而不是前一个。 我也尝试了removeFromParentpresentScene(nil) ,但是它们都不起作用。

您还有其他更好的主意吗? 谢谢

您正在展示新的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类中的所有状态(或至少所有对玩家有意义的状态):当前得分,当前玩家位置,敌人所在的位置以及他们在做什么,等等...无论您的游戏做什么。 SpriteKit类已经支持NSCoding ,因此这是处理保存/恢复的好方法-只需确保您的任何自定义子类(例如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反映了游戏中的实际内容(而不是出于此类SO问题的目的而简化代码),则这是多余的。 您无需为要立即运行的代码创建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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM