I am trying to save a high score using Swift for my SpriteKit game. There are several good examples on StackOverflow, one of which I got to work temporarily, but could not function properly in the Swift file where all of my nodes (and actual game) is located.
*Most of the following code is from a stack overflow answer.
This code I put in a separate file called "HighScore":
import Foundation
class HighScore: NSObject {
var highScore: Int = 0
func encodeWithCoder(aCoder: NSCoder!) {
aCoder.encodeInteger(highScore, forKey: "highScore")
}
init(coder aDecoder: NSCoder!) {
highScore = aDecoder.decodeIntegerForKey("highScore")
}
override init() {
}
}
class SaveHighScore:NSObject {
var documentDirectories:NSArray = []
var documentDirectory:String = ""
var path:String = ""
func ArchiveHighScore(#highScore: HighScore) {
documentDirectories = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
documentDirectory = documentDirectories.objectAtIndex(0) as String
path = documentDirectory.stringByAppendingPathComponent("highScore.archive")
if NSKeyedArchiver.archiveRootObject(highScore, toFile: path) {
println("Success writing to file!")
} else {
println("Unable to write to file!")
}
}
func RetrieveHighScore() -> NSObject {
var dataToRetrieve = HighScore()
documentDirectories = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
documentDirectory = documentDirectories.objectAtIndex(0) as String
path = documentDirectory.stringByAppendingPathComponent("highScore.archive")
if let dataToRetrieve2 = NSKeyedUnarchiver.unarchiveObjectWithFile(path) as? HighScore {
dataToRetrieve = dataToRetrieve2
}
return(dataToRetrieve)
}
}
In the scene where I actually want to get an input and output for the highscore I have:
var Score = HighScore()
override func viewDidLoad() {
super.viewDidLoad()
Score.highScore = 100
SaveHighScore().ArchiveHighScore(highScore: Score)
var retrievedHighScore = SaveHighScore().RetrieveHighScore() as HighScore
println(retrievedHighScore.highScore)
}
So when a particular node passes a "block" the high score should increment accordingly, and then save the number (as long as it is higher than the current highscore.)
func blockRunner() {
Score.highScore = 0
SaveHighScore().ArchiveHighScore(highScore: Score)
var retrievedHighScore = SaveHighScore().RetrieveHighScore() as! HighScore
println(retrievedHighScore.highScore)
for(block, blockStatus) in blockStatuses {
var thisBlock = self.childNodeWithName(block)!
if blockStatus.shouldRunBlock() {
blockStatus.timeGapForNextRun = random()
blockStatus.currentInterval = 0
blockStatus.isRunning = true
}
if blockStatus.isRunning {
if thisBlock.position.x > blockMaxX {
thisBlock.position.x -= CGFloat(groundspeed)
}
else{
thisBlock.position.x = self.origBlockPositionX
blockStatus.isRunning = false
retrievedHighScore.highScore++
if ((retrievedHighScore.highScore % 5) == 0) {
groundspeed++
}
self.scoreText.text = String(retrievedHighScore.highScore++)
}
}else{
blockStatus.currentInterval++
}
}
}
For some reason, it will only increment to 1 and then just display 1 in scoreText, even if it has passed more than one block. If I just declare a normal variable and subtitute it in for retrievedHighScore.highScore++, everything works fine. When I use retrievedHighScore.highScore, it only increments to one and just displays 1 in scoreText, strangely, the 1 isn't even saved.