如何快速保存和加载游戏场景?

时间:2019-01-17 19:58:26

标签: swift sprite-kit persistence nskeyedarchiver nskeyedunarchiver

我正在尝试使游戏场景具有多个spritenodes持久层,以便在将开始按入欢迎屏幕后,加载游戏场景的最后保存状态。我在didMove()中初始化的自定义类中编写了编码/解码方法,并使用nskeyedarchiver来保存游戏场景,但是在加载场景时,场景中的所有变量都设置为nil。这些按钮可以显示并正常工作,但是它们并未链接到场景,并且它们都导致nil进入调试器,因此加载后我试图在场景中执行的任何操作都会导致崩溃。我应该如何更改代码才能使其正常工作?

游戏场景

override func didMove(to view: SKView)
{
    UNUserNotificationCenter.current().delegate = self
    let data = UserDefaults.standard.object(forKey: "bool") as? Bool

    if data == false || data == nil
    {
        NotificationCenter.default.addObserver(self, selector: #selector(Save), name: .Save, object: nil)
        UserDefaults.standard.set(true, forKey: "bool")
        gameVC?.currentScene = self
        let randomPlanetSize = Int.random(in: 160...240)
        planet = self.generateWorld(worldTexture: "planet1", position: nil, size: CGSize(width: randomPlanetSize, height: randomPlanetSize), rotationDuration: 300)
        planet.zPosition=10
        planet.isUserInteractionEnabled=true
        self.addChild(planet)

        ....

        backButton = ReturnButton(texture: SKTexture(image: #imageLiteral(resourceName: "backButton2")), color: .white, size: CGSize(width: 60, height: 30),scene: self,position: CGPoint(x: 50, y: frame.height-80),initpos: CGPoint(x: 50, y: frame.height-80),zpos: 10)

        self.addChild(backButton!)


    }
    else
    {
        backButton?.isUserInteractionEnabled = true
    }

}

返回按钮

class ReturnButton: SKSpriteNode {

var scena: Main_GameScene
var initialPosition = CGPoint()
var goback = false


init(texture: SKTexture?, color: UIColor, size: CGSize, scene: Main_GameScene, position: CGPoint,initpos: CGPoint,zpos: CGFloat) {
    self.scena = scene
    self.initialPosition = initpos
    super.init(texture: texture, color: color, size: size)
    self.position = position
    self.zPosition = zpos
    self.isUserInteractionEnabled = true
    self.colorBlendFactor = 1
}

required convenience init?(coder aDecoder: NSCoder) {
    let scena = aDecoder.decodeObject(forKey: "scenareturn") as! Main_GameScene
    let color = aDecoder.decodeObject(forKey: "coloreturn") as! UIColor
    let size = aDecoder.decodeCGSize(forKey: "sizereturn")
    let text = aDecoder.decodeObject(forKey: "textureturn") as! SKTexture
    let pos = aDecoder.decodeCGPoint(forKey: "positionreturn")
    let initpos = aDecoder.decodeCGPoint(forKey: "initpositionreturn")
    let zpos = aDecoder.decodeObject(forKey: "zposreturn") as! CGFloat

    self.init(texture: text, color: color, size: size,scene: scena,position: pos, initpos: initpos, zpos: zpos)

}
override func encode(with aCoder: NSCoder) {
    aCoder.encode(self.texture, forKey: "textureturn")
    aCoder.encode(self.scena,  forKey: "scenareturn")
    aCoder.encode(self.color, forKey: "coloreturn")
    aCoder.encode(self.size, forKey: "sizereturn")
    aCoder.encode(self.position, forKey: "positionreturn")
    aCoder.encode(self.initialPosition, forKey:"initpositionreturn")
    aCoder.encode(self.zPosition, forKey:"zposreturn")
}
...

游戏视图控制器

  if let data = UserDefaults.standard.object(forKey: "scene") as? Data {

                let scene = NSKeyedUnarchiver.unarchiveObject(with: data) as! Main_GameScene
                let view = self.view as! SKView?
                scene.gameVC=self
                view!.allowsTransparency = true
                view!.backgroundColor = .clear
                scene.backgroundColor = .clear
                scene.scaleMode = .resizeFill
                view!.ignoresSiblingOrder = false
                view!.showsFPS = true
                view!.showsNodeCount = false
                view!.presentScene(scene)
            }

0 个答案:

没有答案