currently I'm working on a game project and I've run into an issue where the game's highscore doesn't update unless I quit the app (completely close) and run the game again. In terms of code I've got this written down.
var data = NSUserDefaults.standardUserDefaults()
//this is when the level is over and the highscore is saved
if score > level1HS{
data.setInteger(score, forKey: "level1HS")
data.synchronize()
}
//and this is in the main menu where the highscore is shown
level1text.text = "\(String(level1HS))"
I've also tried replacing the level1text.text = "\(String(level1HS)" with this level1text.text = "\(level1HS)"
Can somebody please help me find a way to have the game update the highscore as soon as it is achieved ? Thank you!
Wherever you're trying to update the high score, you'll need to listen to the notification for when StandardUserDefaults() gets updated. It would look like this:
let defaults = NSUserDefaults.standardUserDefaults()
let center = NSNotificationCenter.defaultCenter()
center.addObserverForName(NSUserDefaultsDidChangeNotification, object: nil, queue: nil) { (notification) -> Void in
let newScore = defaults.objectForKey("level1HS")
}
Have you tried doing the following?
var level1HS = 10
NSUserDefaults.standardUserDefaults().setObject(highestScore, forKey:"level1HS")
NSUserDefaults.standardUserDefaults().synchronize()
Your problem is probably that you are not using the .synchronize() method.
Also, check out this question:
SpriteKit High Score
Related
I'm learning application development working on a quiz game. I'd like to add statistics to the game. For example, the average score since the app has been downloaded. How can I store the scores on the device in order to reuse them after the app has been closed?
You should take a look at UserDefault. It's basically a dictionary that persists until the user uninstalls your app. I like to write a wrapper around it to get strong typing and ease of reference:
struct Preferences {
static func registerDefaults() {
UserDefaults.standard.register(defaults: [kAverageScore: 0])
}
// Define your key as a constant so you don't have to repeat a string literal everywhere
private static let kAverageScore = "averageScore"
static var averageScore: Double {
get { return UserDefaults.standard.double(forKey: kAverageScore) }
set { UserDefaults.standard.set(newValue, forKey: kAverageScore) }
}
}
Here's how to use it: before you call it for the first time in your app, you must register the defaults. These are the values that your app ships with. On iOS, it only really matters for the very first time the user launches your app. On OS X, do this every time your app starts because the user can delete the app's preferences from ~/Library/Application Support.
// You usually do this in viewDidLoad
Preferences.registerDefaults()
From then on, getting and setting the property is easy:
let averageScore = Preferences.averageScore
Preferences.averageScore = 5.5
You should take a look at UserDefaults
Example
let defaults = UserDefaults.standard
defaults.set(25, forKey: "Age")
defaults.set(true, forKey: "UseTouchID")
defaults.set(Double.pi, forKey: "Pi")
To read values back
let age = defaults.integer(forKey: "Age")
let useTouchID = defaults.bool(forKey: "UseTouchID")
let pi = defaults.double(forKey: "Pi")
UserDefaults
After trying to submit my game to the app store, my app got rejected because of some bug that's working on an iPad 2. I tried to find the problem, and it was because of some high score bug. This happens when the player gets 0 for the first time, right on the scene that shows your score and high score. Here's the code:
var highScoreDefault = NSUserDefaults.standardUserDefaults()
//Right below is the problem
highScore = highScoreDefault.valueForKey("highScore") as NSInteger
Here's the error I get if I get 0 for the first time:
EXC_BAD_INSTRUCTION (code=EXC_1386_INVOP,subcode=0x0)
I keep trying to find a different but a simple way to add the high score, but I can't find it. Please help!
Note: I'm running on Xcode 6.2 in Swift, and this happened on all iOS simulators.
Without more code... Try just make if let statement
something like:
if let value = highScoreDefault.valueForKey("highScore") as? NSInteger {
highScore = value
} else {
highScore = 0
}
This question already has answers here:
Swift - Saving highscore using NSUserDefaults
(5 answers)
Closed 6 years ago.
I am searching for an efficient way to store a "high score" integer in this simple game I am building with Swift in iOS. I want it to keep track of it even if the player shuts down the app, closes it, and restarts it. How should I use the NSUserDefaults function to save this data? Thanks in advance! :)
//TO SAVE INTO USER DEFAULT
NSUserDefaults.standardUserDefaults().setInteger(1234, forKey: "highScore")
//TO RETRIEVE FROM USER DEFAULT
var highScore = NSUserDefaults.standardUserDefaults().integerForKey("highScore")
Save that highscore like this:
let highscore = 20
let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setValue(highscore, forKey: "highscore")
userDefaults.synchronize() // it is not necessary
When you want to get the info, you have to "read" the highscore from the dictionary like this:
if let highscore = userDefaults.valueForKey("highscore") {
// do something here when a highscore exists
}
else {
// no highscore exists
}
I have a spritekit game which I have a highscore in. It uses NSUser Default. But I get the highscore 2, and then I close the app completely, and then open it it shows my highscore 2, and then get one as a score. It remains as 2. However, I close the app again and open it, it shows the highscore 1. Why does it do this? This is my code. Does the if condition not work? Note: This is just narrowed down to Highscore code.
import SpriteKit
//In the DidMoveToView function
if let Highscore1 = defaults.stringForKey("Highscore"){
HighScoreLabel.text = "HIGHSCORE: \(Highscore1)"
}
//In the touches began func
//Making what happens when the User Fails and a new highscore is achieved
if Score > highscore {
defaults.setObject("\(Score)", forKey: "Highscore")
}
Thank you in advance
The issue is you are reading the highscore from NSUserDefaults and showing it in the HighScoreLabel. But you didn't assigned/stored the value in highscore variable, because of that it remains at 0. That makes the following condition true when you open the app and plays for the first time:
if Score > highscore {
defaults.setObject("\(Score)", forKey: "Highscore")
}
You need to change the high score reading part like:
if let Highscore1 = defaults.stringForKey("Highscore") {
HighScoreLabel.text = "HIGHSCORE: \(Highscore1)"
// Storing current high score to variable
highscore = Int(Highscore1)
}
I have an app with a score and highscore system. I can display the highscore within the gameplay scene, but it shows up as 0 in the menu scene. In the gameplay scene I create the variable
var highScore = 0
then I say
if (score > highscore) { score = highscore
I display it inside that scene, I go back to the menu scene and it accesses it by saying
highscoreLabel = actionscene.highscore
(actionscene being the name of the file for my game play scene.) Since the
original value of highscore is 0, it displays 0. How can I fix this or program it in a different way?
You can use NSUserDefaults as an easiest solution. In the GameScene:
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setInteger(10, forKey: "highscore")
defaults.synchronize()
In another scene (MenuScene) :
let defaults = NSUserDefaults.standardUserDefaults()
let highscore = defaults.integerForKey("highscore")
Also note that the synchronize() method, is automatically invoked at periodic intervals, and it keeps in-memory cache in sync with a user’s defaults database.
Ideally, you would let the system to worry about when the persistent storage is updated, but there are cases when you want to do it by yourself and call synchronize() manually:
Because this method is automatically invoked at periodic intervals,
use this method only if you cannot wait for the automatic
synchronization (for example, if your application is about to exit) or
if you want to update the user defaults to what is on disk even though
you have not made any changes.