How to Transfer the User's Score to Another Scene in Swift and Spritekit

How do I transfer the user's score to another scene in Swift and SpriteKit?

You can use NSUserDefaults class as an easiest solution...

In your GameplayScene you set score into persistent storage.

let defaults = NSUserDefaults.standardUserDefaults()
defaults.setInteger(score, forKey: "scoreKey")

defaults.synchronize()

Later in GameOver scene, you read persistent storage like this:

let defaults = NSUserDefaults.standardUserDefaults()
let score = defaults.integerForKey("scoreKey")
println(score)

About synchronize() method (from the docs):

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.

Or I guess you can make a public property (score) on a GameOver scene, and when transitioning, to set that property (from a Gameplay scene) with a current score.

Similarly, you can set a value to userData property which every node has, like this:

 newScene.userData?.setValue(score, forKey: "scoreKey")

EDIT:

NSUserDefaults would be a preferred way if you are interested into a persistence (making a value available between app launches). Otherwise, you can use userData or a struct like pointed by KnightOfDragon in his example.

Swift: How to keep track of and communicate scores between scenes in SpriteKit

NSUserDefaults is a great way to keep track of scores.

To save the high score:

let x : Int = 45 // This int is your high score
var myString = String(x) // This String is you high score as a String

var defaults = NSUserDefaults.standardUserDefaults()

defaults.setObject(myString, forkey : "High_Score") // Saving the String to NSUserDefaults

To access the high score:

var defaults = NSUserDefaults.standardUserDefaults()

var HighScore = defaults.objectForKey("High_Score") // Retrieving your high score as a String

Use a Variable in a different Scene

If you use user defaults correctly you should be able to read and write from any object as UserDefaults.standard is a singleton. Something along these lines should work:

private let scoreUserDefaultsKey = "scoreUserDefaultsKey"

func save(score: Int)
{
let userDefaults = UserDefaults.standard
userDefaults.set(score, forKey: scoreUserDefaultsKey)
userDefaults.synchronize()
}

func read() -> Int
{
return UserDefaults.standard.integer(forKey: scoreUserDefaultsKey)
}

class GameScene1: SKScene {

func saveFromGameScene1(score: Int) {
save(score: score)
}
}

class GameScene2: SKScene {

func readFromGameScene2() -> Int {
return read()
}
}

Said that you could have a much nicer architecture implementing a ScoreManager object and inject it (instead of having hard dependencies on a singleton) into your game scenes.

UPDATE:
Just seen your code snippet. You need to use set, not setValue. setValue is not a method of UserDefaults but is a method of NSObject for KVO.

func setValue(_ value: Any?, forKey key: String)

Sets the property of the receiver specified by a given key to a given
value. If key identifies a to-one relationship, relate the object
specified by value to the receiver, unrelating the previously related
object if there was one. Given a collection object and a key that
identifies a to-many relationship, relate the objects contained in the
collection to the receiver, unrelating previously related objects if
there were any.

The search pattern that setValue:forKey: uses is described in Accessor
Search Patterns in Key-Value Coding Programming Guide.

In a reference-counted environment, if the instance variable is
accessed directly, value is retained.

That is not what you're looking for ;)

Also after you call set make sure to call synchronize as well to be certain that the value is stored immediately.

I hope this helps.

How to save and print the high score into the next scene?

A few Options might be:

1. Save highscore in app delegate. I gameover scene print it from appDelegate.
2. Save highscore in NSUserDefault. then in GameOverScene show it form there.
3. Create a property in GameOverScene and while navigating to GameOverSecne from GameScene set that property.

Here is some tutorial on NSUserDefault, Passing data between ViewControllers.

Hope this helps... :)

How to transfer score from Game Scene to GameViewController

Since your GameViewController is presenting your GameScene you can just hold a reference to it and get the score and high score from properties in your GameScene.

Something like this:

class GameViewController: UIViewController {
var gameScene: GameScene!

override func viewDidLoad() {
super.viewDidLoad()
// Hold a reference to your GameScene after initializing it.
gameScene = SKScene(...)
}
}

class GameScene: SKScene {
var currentScore: Int = 0
var highScore: Int = 0

func updateScore(withScore score: Int) {
currentScore = score
highScore = currentScore > score ? currentScore : score
}
}

Update:

You could use this values in your pressedShareButton like this:

func pressedShareButton(sender: UIButton!) {
let currentScore = scene.currentScore
let highScore = scene.highScore
...
let myText = "WOW! I made \(currentScore) points playing #RushSamurai! Can you beat my score? https://itunes.apple.com/us/app/rush-samurai/id1020813520?ls=1&mt=8"
...

}

How do I pass data between two scenes in Swift?

OK! So instead of using a segue. WHICH YOU CANNOT DO WITH AN SKSCENE. I used a struct. I put the struct outside of one of my scenes that I wanted data to be passed from, and made sure the data was being fed into the struct. I then accessed the struct from another scene and it works perfectly!

struct Variables {
static var aVariable = 0
}

this is the struct^ I have it set to 0 but it will be updated automatically when the score is recorded at the end of the run of my game.
I then accessed it like so in another scene:

print(Variables.aVariable)

This prints the variable from the struct in my new scene. I can also turn this struct into a string and use it for a labelnode.

How can I transfer highscore in other scene - iOS8 [SWIFT]

To be able to use highscore outside of GameScene, you need to make it global. You can do that by creating a new class and defining it there, or just defining it outside of the GameScene brackets. If these two lines:

var defaults = NSUserDefaults()
var highscore = defaults.integerForKey("highscore")

are inside a set of these: {}, it's not global and your use is restricted.



Related Topics



Leave a reply



Submit