2015-06-23 56 views
-1

我想用我的SpriteKit遊戲的Swift保存高分。在StackOverflow中有幾個很好的例子,其中一個我暫時工作,但是在我所有節點(和實際遊戲)所在的Swift文件中無法正常工作。用Swift保存高分數據

*以下代碼大部分來自堆棧溢出答案。

此代碼我把所謂的「高分」一個單獨的文件:

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

我真的推薦在這種情況下使用NSUserDefaults來堅持你的高分。爲了簡單地使用Integer變量,我還建議不要創建高分數對象。你通過利用一個類來建立一個簡單的整型來創建大量不必要的開銷。通過調用NSUserDefaults.standardUserDefaults().setInteger(highScore, forKey: "Highscore")

當需要覆蓋的高分(當一個新的高分是爲了取代舊的),你可以簡單地覆蓋舊的高分:

歸檔高分所有的代碼可以簡化爲1線上面的代碼行再次。

您節省了大量工作,並且您的代碼將更高效地執行。在您的情況下使用類來存儲單個值類型是一個糟糕的選擇。 Crusty會發瘋...

+0

謝謝Kelvin。儘管我對語法仍有點不清楚。所以說我沒有上面的代碼,我重新開始:我聲明一個「highScore」變量並將其設置爲0.然後,我遞增「highScore」,運行該代碼行,然後println(Highscore)和I得到1.現在,如果我關閉模擬器,刪除增量,再次println(Highscore),它等於0.我如何使用它來保存該值?我可以看到一個非常基本的例子嗎?謝謝。 – TerranceW