I'm trying to create my first sprite kit swift game, and I have my game data working using nsuserdefaults. I want to make it more safe so I'm attempting to transition to NSCoding, but nothing I've found online has helped me completely and has just confused me (so sorry if an answer already exists, I probably already looked at it and wasn't able to understand.)
This is my GameState class:
class GameState {
var score: Int
var highScore: Int
var stars: Int
var sound: Bool
var carType: Int
var xSize: Double
var ySize: Double
var gameOver: Bool
class var sharedInstance: GameState {
struct Singleton {
static let instance = GameState()
}
return Singleton.instance
}
init() {
// Init
score = 0
highScore = 0
stars = 0
carType = 1
sound = true
xSize = 1
ySize = 1
gameOver = false
// Load game state
let defaults = NSUserDefaults.standardUserDefaults()
highScore = defaults.integerForKey("highScore")
stars = defaults.integerForKey("stars")
sound = defaults.boolForKey("sound")
carType = defaults.integerForKey("carType")
xSize = defaults.doubleForKey("xSize")
ySize = defaults.doubleForKey("ySize")
gameOver = defaults.boolForKey("gameOver")
}
func saveState() {
// Update highScore if the current score is greater
highScore = max(score, highScore)
// Store in user defaults
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setInteger(highScore, forKey: "highScore")
defaults.setInteger(stars, forKey: "stars")
defaults.setBool(sound, forKey: "sound")
defaults.setInteger(carType, forKey: "carType")
defaults.setDouble(xSize, forKey: "xSize")
defaults.setDouble(ySize, forKey: "ySize")
defaults.setBool(gameOver, forKey: "gameOver")
NSUserDefaults.standardUserDefaults().synchronize()
} }
and I save and load data in my other classes using:
GameState.sharedInstance.*****
How would I go about changing this to implement NSCoding and then load and save the data from other classes? Thanks.
The class you want to save has to conform to the NSCoding
protocol and implement required init(coder aDecoder: NSCoder)
and func encodeWithCoder(aCoder: NSCoder)
.
Here's a simplified example:
class GameState: NSObject, NSCoding {
var score: Int?
var gameOver: Bool?
init(score: Int, gameOver: Bool) {
super.init()
self.score = score
self.gameOver = gameOver
}
required init(coder aDecoder: NSCoder) {
self.score = aDecoder.decodeObjectForKey("score") as? Int
self.gameOver = aDecoder.decodeObjectForKey("gameOver") as? Bool
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(self.score, forKey: "score")
aCoder.encodeObject(self.gameOver, forKey: "gameOver")
}
}
let myGameState = GameState(score: 42, gameOver: true)
Then you can use NSKeyedArchiver
and NSKeyedUnarchiver
, for example in the AppDelegate, to save and load your object as data:
func applicationWillTerminate(aNotification: NSNotification) {
NSKeyedArchiver.archiveRootObject(myGameState, toFile: "a/file/path")
}
func applicationDidFinishLaunching(aNotification: NSNotification) {
if let data = NSKeyedUnarchiver.unarchiveObjectWithFile("a/file/path") as? GameState {
myGameState = data
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With