我正在尝试使用Swift为我的SpriteKit游戏保存高分。 StackOverflow上有几个很好的例子,其中一个我暂时工作,但是在我的所有节点(和实际游戏)所在的Swift文件中无法正常运行。
*以下大部分代码来自堆栈溢出答案。
这段代码我放在一个名为" 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)
}
}
在我实际想要获得高分的输入和输出的场景中,我有:
var Score = HighScore()
override func viewDidLoad() {
super.viewDidLoad()
Score.highScore = 100
SaveHighScore().ArchiveHighScore(highScore: Score)
var retrievedHighScore = SaveHighScore().RetrieveHighScore() as HighScore
println(retrievedHighScore.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++
}
}
}
由于某种原因,它只会增加到1,然后只在scoreText中显示1,即使它已经传递了多个块。如果我只是声明一个普通变量并将其替换为retrieveHighScore.highScore ++,那么一切正常。当我使用retrieveHighScore.highScore时,它只增加到1,只在scoreText中显示1,奇怪的是,1甚至没有保存。
答案 0 :(得分:1)
我真的建议在这种情况下使用NSUserDefaults
来保持你的高分。我还建议不要仅仅为了拥有一个Integer变量而创建一个highscores对象。您可以通过利用类来模拟简单的整数来创建大量不必要的开销。
归档高分的所有代码都可以简化为1行:NSUserDefaults.standardUserDefaults().setInteger(highScore, forKey: "Highscore")
当您需要覆盖高分(当新的高分将替换旧分数时),您可以通过再次调用上面的代码行来覆盖旧的高分。
您可以节省大量工作,并且您的代码将更有效地执行。使用类在您的情况下存储单个值类型是一个可怕的选择。暴躁会生气......