使用 UserDefaults 存储唱首歌游戏的分数 (Swift 5)

Using UserDefaults to store score for a clicker game (Swift 5)

做了一个简单的增量游戏。我想要它,这样即使我转到另一个 VC 然后 return 到游戏,或者重新打开游戏,它也会显示当前分数。我的问题是,如果我离开游戏,那么分数将 return 归零。我不希望发生这种情况。分数不应该被重置。我听说我可以使用 UserDefaults,但我对它一点都不熟悉。如果你能用代码解释,那将是最好的。谢谢

import UIKit

class CookieClickerVC: UIViewController {

@IBOutlet weak var goldLabel: UILabel!
@IBOutlet weak var numberOfGold: UILabel!
@IBOutlet weak var getGoldButton: UIButton!

override func viewDidLoad() {
    super.viewDidLoad()
    formatItems()
    let defaults = UserDefaults.standard
    defaults.set(0, forKey: "goldCount")

}



@IBAction func getGoldClicked(_ sender: Any) {
    goldCount += 1
    numberOfGold.text = ("\(goldCount)")
}`

另外,您可能已经想通了,但 goldCount 是一个未解析的标识符。单击按钮后我应该如何更改代码?

import UIKit

class CookieClickerVC: UIViewController {

@IBOutlet weak var goldLabel: UILabel!
@IBOutlet weak var numberOfGold: UILabel!
@IBOutlet weak var getGoldButton: UIButton!

private var goldCount: Int = Int()

override func viewDidLoad() {
    super.viewDidLoad()
    formatItems()

}



@IBAction func getGoldClicked(_ sender: Any) {
    goldCount += 1

    numberOfGold.text = ("\(goldCount)")

    UserDefaults.standard.set(goldCount, forKey: "goldCount")

    UserDefaults.standard.synchronize()

   //To get the count again you can use

     print(UserDefaults.standard.integer(forKey: "goldCount")
}

只要有增量,您就可以像这样在 UserDefault 中保存 goldCount 的值,我还添加了如何从 UserDefault 中获取相同的值。

您可以使用这些 funtions 来获取和设置分数

class CookieClickerVC: UIViewController {

    @IBOutlet weak var goldLabel: UILabel!
    @IBOutlet weak var numberOfGold: UILabel!
    @IBOutlet weak var getGoldButton: UIButton!


   lazy var goldCount : Int = 0 {
         didSet {
        numberOfGold.text = ("\(goldCount)")
       }
   }

   override func viewDidLoad() {
        super.viewDidLoad()
        formatItems()
        goldCount = getScore()

    }

    @IBAction func getGoldClicked(_ sender: Any) {
        goldCount += 1
        savescore(goldCount)
    }

    //  Save and Get methods ..

    func saveScore(_ score:Int) {
            let defaults = UserDefaults.standard
            defaults.set(score, forKey: "goldCount")
          //  defaults.synchronize() its [unnecessary][1] 
        }

// defaults.synchronize() its unnecessary

    func getScore()-> Int {
          let defaults = UserDefaults.standard
          return  defaults.integer(forKey: "goldCount")
        }
}

第 1 步: 声明您的 goldCount 变量并将初始值设置为 0

第 2 步: on viewDidLoad,获取存储在 UserDefaults 中的值并将其设置为 goldCount

第 3 步:同时更新您的标签

第 4 步:更新 userDefaults

goldCount 的值
import UIKit

class CookieClickerVC: UIViewController {

    @IBOutlet weak var goldLabel: UILabel!
    @IBOutlet weak var numberOfGold: UILabel!
    @IBOutlet weak var getGoldButton: UIButton!

    //Step1: declare your goldCount variable and set initial value to 0
    var goldCount = 0

    override func viewDidLoad() {
        super.viewDidLoad()
        formatItems()
        //Step2: on viewDidLoad, get the value stored in the UserDefaults and set it to goldCount
        goldCount = UserDefaults.standard.integer(forKey: "goldCount")
        //Step3: then also update your label
        numberOfGold.text = ("\(goldCount)")


    }

    @IBAction func getGoldClicked(_ sender: Any) {
        goldCount += 1
        numberOfGold.text = ("\(goldCount)")
        //Step4: update the value of goldCount in userDefaults
        UserDefaults.standard.set(goldCount, forKey: "goldCount")
    }
}

试试下面的方法

class ViewController: UIViewController {

    @IBOutlet weak var numberOfGold: UILabel!
    @IBOutlet weak var highScore: UILabel!

    //declare your count variable globally
    var goldCount : Int = 0
    let defaults = UserDefaults.standard

    override func viewDidLoad() {
        super.viewDidLoad()
        //get the highscore and then set it to label
        let userHighScore = getUserScore()
        highScore.text = "\(userHighScore)"

    }

    @IBAction func goldButtonClicked(_ sender: Any) {
        goldCount += 1
        numberOfGold.text = "\(goldCount)"
    }

    //function to say game finished and store the score in userdefault
    //call this function when the gameHasFinished
    func gameFinished() {
        saveUserScore(goldCount)
    }

    func saveUserScore(_ score:Int){
        defaults.set(score, forKey: "goldCount")
    }
    func getUserScore()-> Int {
        return  defaults.integer(forKey: "goldCount")
    }
}

您可以更改 viewDidLoad 函数以首先检查 UserDefaults 中的 "goldCount" 键,如果它有值,则使用它。如果不只是将分数设置为 0.

override func viewDidLoad() {
    super.viewDidLoad()
    formatItems()
    let defaults = UserDefaults.standard

    if let savedScore = defaults.value(forKey: "goldCount") as? Int {
        goldCount = savedScore
    } else {
        defaults.set(0, forKey: "goldCount")
    }
}

您可以将 "goldCount" 定义为 IBOutlet 下方的 var goldCount: Int = 0

另外,作为进一步的优化,您可以提取 "goldCount" 字符串用作 let goldCountKey: String = "goldCount" 并像 defaults.set(0, forKey: goldCountKey) 一样使用它。在我看来,避免硬编码字符串是一种很好的做法,但在这种情况下并不是那么重要。

要在每次点击时保存新值,请在 getGoldClicked 中添加 UserDefaults.standard.set(goldCount, forKey: goldCountKey)。这里的另一个想法是将此添加到 AppDelegatewillTerminate 函数中,以确保在应用程序终止时保存您的值。虽然这需要引用那里的 goldCount 值,所以不要着急。

希望对您有所帮助!