在 Swift 3 中使用 UserDefaults 保存高分

save a highscore with UserDefaults in Swift 3

class ThirdViewController: UIViewController {

var i = 3

var a: Double = 0

var fastestScore:Float = 100000000000000.0

var randomNumberX = Int(arc4random_uniform(375))

var randomNumberY = Int(arc4random_uniform(667))


@IBOutlet weak var fastestScoreLabel: UILabel!

@IBOutlet weak var homeButtonLabel: UIButton!

@IBOutlet weak var finalLabel: UILabel!

@IBOutlet weak var playAgainButtonLabel: UIButton!

@IBOutlet weak var circleImage: UIButton!

@IBOutlet weak var secondTimerLabel: UILabel!

@IBOutlet weak var counterLabel: UILabel!

var timerA = Timer()

var timerB = Timer()

@IBAction func homeButton(_ sender: Any) {

    nextPage = false

}

@IBAction func playAgainButton(_ sender: Any) {

    randomNumberX = Int(arc4random_uniform(375))

    randomNumberY = Int(arc4random_uniform(667))

    homeButtonLabel.isHidden = true

    counterLabel.text = "3"

    i = 3

    timerA = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ThirdViewController.counterFunc), userInfo: nil, repeats: true)

    a = 0

    counterLabel.isHidden = false

    playAgainButtonLabel.isHidden = true

    circleImage.isHidden = true

    finalLabel.isHidden = true

    secondTimerLabel.isHidden = true

    fastestScoreLabel.isHidden = true

}

@IBAction func circleButton(_ sender: Any) {

    fastestScoreLabel.isHidden = false

    circleImage.isHidden = true

    homeButtonLabel.isHidden = false

    timerB.invalidate()

    playAgainButtonLabel.isHidden = false

    var saying = ""

    if a < 0.2 {

        saying = "That's actually pretty good \(a) seconds is pretty fast"

    } else if a >= 0.2 && a <= 0.45 {

        saying = "\(a) seconds is not really that good"

    } else {

        saying = "\(a) seconds? Seriously? Are you even trying?"

    }

    finalLabel.text = saying

    finalLabel.isHidden = false

    if Float(a) < fastestScore {

        fastestScore = Float(a)

        UserDefaults.standard.set(fastestScore, forKey: "Fastest Score")

        let savedFastestScore = UserDefaults.standard.float(forKey: "Fastest Score")

        fastestScoreLabel.text = String(savedFastestScore)

    }


}

func secondTimer() {

    a = a + 0.01

    secondTimerLabel.text = String(a)

}

func counterFunc() {

    if i > 1 {

        i -= 1

        counterLabel.text = String(i)

    } else {

        timerB = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(ThirdViewController.secondTimer), userInfo: nil, repeats: true)

        circleImage.isHidden = false

        self.circleImage.center = CGPoint(x:randomNumberX, y:randomNumberY)

        counterLabel.isHidden = true

        timerA.invalidate()

        secondTimerLabel.isHidden = false

    }

}

override func viewDidLoad() {
    super.viewDidLoad()


    fastestScoreLabel.isHidden = true

    homeButtonLabel.isHidden = true

    playAgainButtonLabel.isHidden = true

    circleImage.isHidden = true

    secondTimerLabel.isHidden = true

    timerA = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ThirdViewController.counterFunc), userInfo: nil, repeats: true)

    // Do any additional setup after loading the view.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

/*
// MARK: - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    // Get the new view controller using segue.destinationViewController.
    // Pass the selected object to the new view controller.
}
*/

}

我曾多次尝试使用 userDefaults 尝试在您关闭时保存高分,但我似乎做不到。如果有人知道如何做,我将不胜感激哈哈。

保存高分时,请确保您的当前分数大于新分数。

假设当前最高分是100

 var fastestScore = 100 
 var currentScore: Int?


if currentScore < fastestScore { 
          Userdefaults.standard.set(currentScore, forKey: "Fastest Score") 


}

上面的代码将转到您需要保存最高分的函数。也许在你的游戏结束场景中。

要检索低分,请执行此操作

var savedFastestScore = UserDefaults.standard.float(forKey: "Fastest Score")

您仍然没有清楚地解释您遇到的问题,但我的猜测是您的高分似乎没有在应用程序重新启动时保存。

问题是在创建 ThirdViewController 时将 fastestScore 初始化为 100000000000000.0。您不从 UserDefaults 加载它。因此,即使存在已存储的 fastestScore,您也不会在启动时加载它。

您应该通过两个更改来解决此问题。首先,在你的应用委托中,你应该注册一个默认的高分:

let bestScoreKey = "bestScore"

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, willFinishLaunchingWithOptions options: [UIApplicationLaunchOptionsKey : Any]?) -> Bool {
        UserDefaults.standard.register(defaults: [
            bestScoreKey: 1_000_000_000.0
        ])
        return true
    }

}

您还应该在那里注册任何其他默认设置。

其次,在ThirdViewController中,你应该从UserDefaults初始化fastestScore。您还可以在 属性 的 didSet 观察器中将更改保存回 UserDefaults

    var fastestScore: Double = UserDefaults.standard.double(forKey: bestScoreKey) {
        didSet {
            UserDefaults.standard.set(fastestScore, forKey: bestScoreKey)
        }
    }

其他提示:

  • 如果你的分数是 Double,就没有理由让 fastestScore 成为 Float。只需将其保存为 Double.

  • 不要重复字符串键。编译器不会发现您的拼写错误。像我对 bestScoreKey.

  • 所做的那样,将密钥放在常量中
  • 您可以在长数字中使用 _ 以使其更具可读性。

  • 侮辱您的玩家是一种有问题的营销策略。如果对你问题的第一条评论是“认真的?你在努力吗?”