使用Swift保存高分数据

时间:2015-06-23 21:47:17

标签: swift save nsdocument

我正在尝试使用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甚至没有保存。

1 个答案:

答案 0 :(得分:1)

我真的建议在这种情况下使用NSUserDefaults来保持你的高分。我还建议不要仅仅为了拥有一个Integer变量而创建一个highscores对象。您可以通过利用类来模拟简单的整数来创建大量不必要的开销。

归档高分的所有代码都可以简化为1行:NSUserDefaults.standardUserDefaults().setInteger(highScore, forKey: "Highscore")

当您需要覆盖高分(当新的高分将替换旧分数时),您可以通过再次调用上面的代码行来覆盖旧的高分。

您可以节省大量工作,并且您的代码将更有效地执行。使用类在您的情况下存储单个值类型是一个可怕的选择。暴躁会生气......