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.
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
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)
}
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
I am using NSUserDefaults to display the score from my GameScene on my resetViewController. The problem is that if the user doesn't score it will display the players last score.
In GameScene
var score: Int = 0
var scoreLabel = SKLabelNode()
let defaults = NSUserDefaults.standardUserDefaults()
score++
scoreLabel.text = "\(score)"
defaults.setObject(scoreLabel.text, forKey: "scoring")
In resetViewController
var score = defaults().stringForKey("scoring")
YourScore.text = score
I'm sure it's something simple but I can't seem to figure it out
When you need to score to reset, just call
NSUserDefaults.standardUserDefaults().setObject(nil, forKey: "scoring")
removeObjectForKey: removes the value from NSUserDefaults. You could also set it to zero. Or just not use NSUserDefaults -- there's not much point in using it unless you need to persist the value between restarts of your app.
I suggest saving the integer, not the string. That way the default will be zero, and you can easily reset the score by setting the key to zero.
NSUserdefaults.standardUserDefaults().IntegerForKey("score")
NSUserdefaults.standardUserDefaults().setInteger(0, forKey: "score")
my NSUserDefaults doesn't save my game high score properly. When am playing(testing) the game it works ok but when i quit(terminate) and restart or when i transition from scene to scene my high score goes back to 0. can anyone help me fix this issue? thank in advance.
var score = 6
NSUserDefaults.standardUserDefaults().integerForKey("highscore")
//Check if score is higher than NSUserDefaults stored value and change NSUserDefaults stored value if it's true
if score > NSUserDefaults.standardUserDefaults().integerForKey("highscore") {
NSUserDefaults.standardUserDefaults().setInteger(score, forKey: "highscore")
NSUserDefaults.standardUserDefaults().synchronize()
}
NSUserDefaults.standardUserDefaults().integerForKey("highscore")
The problem is that this statement, which appears twice, does nothing at all:
NSUserDefaults.standardUserDefaults().integerForKey("highscore")
It fetches the "highscore" key's value from user defaults, but immediately throws it away, because you are not assigning the result to anything, like this:
let highscore = NSUserDefaults.standardUserDefaults().integerForKey("highscore")
Thus, even though you are successfully storing the high score in user defaults, you are never retrieving it - so there is no basis for your claim that it is not being saved, because you have given yourself no way of knowing whether or not is has been saved.