Reputation: 11
I am looking for some advice when it comes to saving a score in my app - I currently have a coin count working in which through my HUD class when I collide through Coins the value increases accordingly. My next step is trying to initiate a high-score that initiates, after some research I think the topic I am looking into is based around NSUserDefaults
..
The current code :
import SpriteKit
class HUD: SKNode {
//An SKLabelNode to print the coin score:
let coinCountText = SKLabelNode(text: "000000")
func createHUDNodes(){
// Configure the coin text label:
coinCountText.fontName = "STHupo-Heavy-Italic"
let coinTextPosition = CGPoint(x: -cameraOrigin.x + 770, y: coinPosition.y)
coinCountText.position = coinTextPosition
coinCountText.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.left
coinCountText.verticalAlignmentMode = SKLabelVerticalAlignmentMode.center
// Add the text label and coin icon to the HUD:
self.addChild(coinCountText)
}
func setCoinCountDisplay(newCoinCount:Int) {
let formatter = NumberFormatter()
let number = NSNumber(value: newCoinCount)
formatter.minimumIntegerDigits = 6
if let coinStr =
formatter.string(from: number) {
// Update the label node with the new count:
coinCountText.text = coinStr
}
}
Working in the HUD class I think naturally I would need to create another 'SKlabelNode'for the highscore node which I can duplicate from the code that works above.. my problem is how can I implement a highscore feature in the app, as when closed and re-opening the application it will remember the highscore..
I assume the following code would need to be added but I do not understand how it ties together in the class.
var currentHighScore =
NSUserDefaults.standardUserDefaults().integerForKey("coin_highscore")
var highScoreLabel = SKLabelNode(fontNamed:"STHupo-Heavy-Italic")
highScoreLabel.text = ""
highScoreLabel.fontSize = 45
highScoreLabel.position = CGPoint(x: viewSize.width * 0.5, y: viewSize.height * 0.30)
self.addChild(highScoreLabel)
if (score > currentHighScore) {
NSUserDefaults.standardUserDefaults().setInteger(score, forKey: "player_highscore")
NSUserDefaults.standardUserDefaults().synchronize()
highScoreLabel.text = "New High Score: \(score) !"
} else {
highScoreLabel.text = "Better Luck Next Time: \(score)"
}
}
Any advice on how I could integrate this code would be much appreciated.
, AJ
Revised :
else if nodeTouched.name == "returnToMenu"{
// Transition to the main menu scene
self.view?.presentScene(MenuScene(size: self.size),transition.crossFade(withDuration: 0.6))
let currentHighScore = UserDefaults.standard.integer(forKey: "Player_highscore")
let highScoreLabel = SKLabelNode(fontNamed:"STHupo-Heavy-Italic")
highScoreLabel.text = "Value: \ (String(describing: coin.value))"
highScoreLabel.text = ""
highScoreLabel.fontSize = 45
highScoreLabel.zPosition = 100
highScoreLabel.position = CGPoint(x: 50, y: 50)
self.addChild(highScoreLabel)
if (coin.value > currentHighScore) {
UserDefaults.standard.set(coin.value, forKey: "Player_highscore")
UserDefaults.standard.synchronize()
highScoreLabel.text = "New High Value: \(String(describing: coin.value)) !"
} else {
highScoreLabel.text = "Better Luck Next Time: \(String(describing: coin.value))"
}
}
}
}
I am assuming it's the referencing to my original HUD that is causing the problem? In my coin class I declared the coin.value = 5, each time the coin is collected by coinCountDisplay increases accordingly. However still does not show - :/
Upvotes: 0
Views: 129
Reputation: 54621
Extending on Frankenstein's answer, IF you want to use Swift 5 you can use Property Wrappers
to avoid writing get
and set
every time:
@propertyWrapper struct UserDefaultsBacked<Value> {
let key: String
let defaultValue: Value
var storage: UserDefaults = .standard
var wrappedValue: Value {
get {
let value = storage.value(forKey: key) as? Value
return value ?? defaultValue
}
set {
storage.setValue(newValue, forKey: key)
}
}
}
And use it like this:
@UserDefaultsBacked(key: "coin_highscore", defaultValue: 0)
var coinHighscore: Int
Upvotes: 1
Reputation: 16361
Add a property to your view controller with both get and set and use it in all the places. The get method should get the value from UserDefaults
and the set should update the value in UserDefaults
.
var coinHighscore: Int {
get {
UserDefaults.standard.integer(forKey: "coin_highscore")
}
set {
UserDefaults.standard.set(newValue, forKey: "coin_highscore")
}
}
Upvotes: 1