如果没有重置游戏,我如何在场景之间进行切换,因为didMoveToView()
被调用并重新初始化了我的所有实例变量。例如,我有一个游戏场景和一个商店场景。当我从我的商店场景过渡到我的游戏时,游戏重置。有没有办法防止这种情况或如何在场景之间转换时保持相同的游戏状态?
答案 0 :(得分:3)
关于你的问题我想把你的注意力集中在三个方面:
1)您可以创建一个包含共享属性的类,而不是每次在SKScene
或SKNode
中重复相同的共享属性(struct,vars或自定义类..)。
2)您的项目非常适合拥有一些共享实例管理器:例如,具有项目所有管理器(共享实例类)属性的游戏管理器(共享实例类)(以下示例):
您的游戏属性模型,如设置和游戏变量。
3)如果您需要在场景中使用rootNode
(要添加要暂停的元素而不是另一个,要将对象添加到同一个锚定节点,以创建背景..)您可以继承到具有此属性的自定义SKScene
。
一些代码显示你的项目如何出现,从GameManager开始:
class GameManager: NSObject {
static let sharedInstance = GameManager()
var allProducts = Products()
}
您的GameScene Class实例可以像这样访问GameManager的单个实例:
class GameScene: SKScene {
let gameManager = GameManager.sharedInstance
override func didMoveToView(view: SKView) {
print("the current number of shoes is \(self.gameManager.allProducts.shoes)")
}
}
您的ShopScene Class实例可以像这样访问同一个GameManager实例:
class ShopScene: SKScene {
let gameManager = GameManager.sharedInstance
override func didMoveToView(view: SKView) {
print("the current number of shoes is \(self.gameManager.allProducts.shoes)")
}
}
答案 1 :(得分:2)
您有很多选项可以在游戏场景中保持持久状态。我已经列出了我使用的两种方法。
选项A:维护对场景的引用
当场景换出新场景时,场景通常会从内存中完全删除。如果您在其他地方保留场景对象的引用,并显示该引用,则不会丢失任何数据。
为了保持一段时间的参考(并在需要时再次呈现场景),我推荐一个带有静态实例的场景演示者类,如下所示:
class SceneCoordinator {
static var shared = SceneCoordinator()
var gameScene : GameScene?
var shopScene : ShopScene?
}
初始化GameScene
时,也请将其注册到SceneCoordinator.shared.gameScene = self
。然后,当转移离开另一个场景时,您可以呈现存储在协调器类中的实例。
didMoveToView()
时,仍然会在场景中调用它。您可以将所有初始化代码移动到单独的函数中,创建一个新的实例var,例如var isInitialized = false
,并且仅在内容为false时初始化您的内容(并在初始化后将其设置为true)。
这种方法的问题是场景对象很昂贵,这意味着你可以通过不允许释放场景来增加大量开销。
选项B:模型结构
更好的方法(也可以在应用关闭后更容易重新启动场景)是创建游戏状态的数据模型,并提供从模型对象创建GameScene的功能。
此方法与模型 - 视图 - 控制器设计模式更加一致,并允许您的场景和数据更轻量级。
如:
struct GameModel {
var coins : Int
}
class GameScene : SKScene {
var state : GameModel
convenience init(size: CGSize, state: GameModel) {
self.state = state
// set up scene content from state
}
// lots of fun game scene logic
func playerCollectedCoin() {
state.coins += 1
}
func moveToShopScene() {
// init a new shop scene with the state of this scene
let shop = ShopScene(size: self.view!.bounds.size, state: self.state)
(self.view as! SKView).presentScene(scene)
}
}
class ShopScene : SKScene {
var state : GameModel
convenience init(size: CGSize, state: GameModel) {
self.state = state
// set up scene content from state
}
// lots of fun shop scene logic
func playerSpentCoins(amount: Int) {
state.coins -= amount
}
func moveToGameScene() {
// init a new game scene with the updated state of this scene
let game = GameScene(size: self.view!.size, state: self.state)
(self.view as! SKView).presentScene(game)
}
}