【问题标题】:Swift, SpriteKit: how to save the whole progress of a sceneSwift,SpriteKit:如何保存场景的整个进度
【发布时间】:2018-03-14 04:09:03
【问题描述】:

我用“GameViewController.swift”构建了一个快速游戏

import UIKit
import SpriteKit

class GameViewController: UIViewController {


override func viewDidLoad() {
    super.viewDidLoad()


    if let scene = GameScene(fileNamed:"GameScene") {
        // Configure the view.
        let skView = self.view as! SKView

        /* Set the scale mode to scale to fit the window */


        scene.scaleMode = .AspectFill

        skView.presentScene(scene)
        }
    }
}

我有一个名为“GameScene”的场景(它是您打开 swift 并创建新的 swift 游戏时的默认游戏文件)

import UIKit
import SpriteKit

class GameScene: SKScene{

var building = SKSpriteNode()

override func didMoveToView(view: SKView) {

    /* Setup your scene here */

}

那里发生了很多事情。 (可以放置建筑物并触发一些动作等)
但是,当您离开应用程序时,所有进度都会丢失。
如何保存这个“GameScene”的整个进度并在开始时重新加载?

【问题讨论】:

  • 使用类或结构创建模型。

标签: ios swift sprite-kit store scene


【解决方案1】:

您可以在applicationDidEnterBackground(_:) 事件中存档您的游戏状态。通过NotificationCenter订阅以获得通知。

class GameScene : SKScene {
    required init?(coder decoder: NSCoder) {
        super.init(coder: decoder)

        NotificationCenter.default.addObserver(self, selector: #selector(applicationDidEnterBackground), name: .UIApplicationDidEnterBackground, object: nil)
    }

    func applicationDidEnterBackground() {
        // Save Scene
        let sceneData = NSKeyedArchiver.archivedData(withRootObject: self)
        UserDefaults.standard.set(sceneData, forKey: "currentScene")
    }

    class func loadScene() -> SKScene? {
        var scene: GameScene?

        if let savedSceneData = UserDefaults.standard.object(forKey: "currentScene") as? NSData,
           let savedScene = NSKeyedUnarchiver.unarchiveObject(with: savedSceneData as Data) as? GameScene {
            scene = savedScene
        } else {
            scene = nil
        }

        return scene
    }
}

场景加载发生在viewDidLoad,首先尝试定位以前存档的场景,如果不存在存档场景,则创建一个新场景。

class GameViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        if let view = self.view as! SKView? {
            guard let scene = GameScene.loadScene() ?? SKScene(fileNamed: "GameScene") as? GameScene else {
                fatalError("Scene not loaded")
            }

            scene.scaleMode = .resizeFill

            view.presentScene(scene)            
            view.ignoresSiblingOrder = true
        }
    }
}

您还需要使游戏元素NSCoding 兼容,如其他答案中所述。

【讨论】:

    【解决方案2】:

    SKScene 符合 NSCoding,因此您可以使用它来存档您的场景。这是一个可能会有所帮助的教程。 https://www.hackingwithswift.com/read/12/3/fixing-project-10-nscoding

    基本思想是获取场景的实例,然后将其存档:

    NSKeyedArchiver.archivedData(withRootObject: scene)

    然后把它保存到磁盘或其他地方

    您可以稍后将其取消归档

    NSKeyedUnarchiver.unarchiveObject(with: scene) as! SKScene

    现在,当您制作自定义场景类时,您需要确保包含您创建的所有需要​​保存的变量。这就是讨厌的 required init(coder aDecoder:NSCoder) 初始化程序出现的地方,人们往往不会使用。

    你基本上使用这个初始化器来解码你的自定义变量,就像这样。

    required init(coder aDecoder: NSCoder) {
        player = aDecoder.decodeObject(forKey: "player") as! String
    }
    

    要将其保存到存档中,请添加编码方法

    func encode(with aCoder: NSCoder) {
        aCoder.encode(player, forKey: "player")
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-11
      • 2015-01-25
      • 2015-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多