1
votes

Utilisation de UserDefaults pour stocker le score d'un jeu de clicker (Swift 5)

J'ai créé un jeu incrémentiel simple. Je veux que même si je vais dans un VC différent et que je retourne au jeu, ou que je rouvre le jeu, il affichera le score actuel. Mon problème est que si je quitte le jeu, le score reviendra à zéro. Je ne veux pas que cela se produise. Le score ne doit pas être réinitialisé. J'ai entendu dire que je pourrais utiliser UserDefaults mais je n'y suis pas du tout familier. Si vous pouvez expliquer en utilisant du code, ce serait mieux. Merci.

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)")
}`

aussi, vous avez peut-être déjà compris, mais goldCount est un identifiant non résolu. Comment changer le code après avoir cliqué sur le bouton?


0 commentaires

5 Réponses :


2
votes
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")
}
Whenever there is an increment you can save the value of goldCount like this in your UserDefault and I have also added how can you fetch the same value from UserDefault.

0 commentaires

5
votes

Vous pouvez utiliser ces fonctions pour obtenir et définir le score

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

// defaults.synchronize () c'est inutile p>

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] 
        }


0 commentaires

6
votes

Étape 1: déclarez votre variable goldCount et définissez la valeur initiale sur 0

Étape 2: strong > sur viewDidLoad , récupérez la valeur stockée dans UserDefaults et réglez-la sur goldCount

Étape 3: Mettez également à jour votre libellé

Étape 4: Mettez à jour la valeur de goldCount dans userDefaults

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")
    }
}


0 commentaires

2
votes

Essayez ce qui suit

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")
    }
}



2
votes

Vous pouvez modifier votre fonction viewDidLoad pour vérifier d'abord la clé "goldCount" dans UserDefaults , et si elle a une valeur, utilisez-la. Sinon, définissez simplement le score sur 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")
    }
}

Vous pouvez définir "goldCount" comme var goldCount: Int = 0 sous votre IBOutlet s.

Aussi comme optimisation supplémentaire, vous pouvez extraire la chaîne "goldCount" à utiliser comme let goldCountKey: String = "goldCount" et l'utiliser comme valeurs par défaut. set (0, forKey: goldCountKey) . Éviter les chaînes codées en dur est une bonne pratique à mon avis, mais pas si cruciale dans ce cas.

Pour enregistrer la nouvelle valeur à chaque clic, ajoutez UserDefaults.standard.set (goldCount, forKey : goldCountKey) dans getGoldClicked . Une autre idée ici serait d'ajouter ceci dans la fonction willTerminate de votre AppDelegate pour vous assurer que votre valeur est enregistrée lorsque l'application est terminée. Bien que cela nécessitera des références à la valeur goldCount, donc pas de précipitation.

J'espère que cela aide!


2 commentaires

defaults.integer (forKey: "goldCount") c'est une valeur "non facultative". pas besoin d'if-let.


Oui, mon mal. J'utilise généralement value (forKey :) et je la lance. Correction de la réponse, merci!