1

I'm trying to make a gamescene whith multiple layers of spritenodes persistent so that after you press start into the welcome screen, the last saved state of the gamescene gets loaded. I wrote encode/decode methods in the custom classes that i initialize in didMove() and i used nskeyedarchiver to save the gamescene, but when it is loaded all the variables of the scene are set to nil. The buttons show up and work, but they are not linked to the scene, and they all result nil into the debugger, so anything that i'm trying to do into the scene after loading results in a crash. How should i change the code to make it work?

Gamescene

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
    }

}

Return Button

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")
}
...

Game view controller

  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)
            }
DavidT
  • 11
  • 2

0 Answers0