isn2011
isn2011

Reputation: 23

Saving a score in Spritekit swift

I am wanting to save a score of which in my game is known as jelly beans. These jelly beans can be spent as a virtual currency, and so will also be influenced by in-app purchases at some point.

So my question is what is the best way to do this. First-time players of the game will start with a jelly bean total of 0. Each time the player levels up they get 10 Jelly Beans. These will need to be added to the overall virtual currency so that this can be spent.

If the player is returning to the game the current total of jelly beans should be displayed and this will increment as usual.

My code is as shown:

import SpriteKit

class GameScene: SKScene {

// Set SKNodes
let buttonOne = SKSpriteNode(imageNamed: "buttonOne")
let buttonTwo = SKSpriteNode(imageNamed: "buttonTwo")
let buttonThree = SKSpriteNode(imageNamed: "buttonThree")
let menuButton = SKSpriteNode(imageNamed: "mainMenu")
let header = SKSpriteNode(imageNamed: "top")
var currentNumber = SKLabelNode()
var levelNumber = SKLabelNode()
var targetNumber = SKLabelNode()
var turnLabel = SKLabelNode()
var beanNumber = SKLabelNode()
let jellyBeanImg = SKSpriteNode(imageNamed: "jellyBean")

// Set Variable Numbers
var targetValue = Int()
var currentValue = Int()
var levelValue = Int()
var jellyBeanValue = Int()
var playerID = Int()
var aiValue = Int(arc4random() % 4)

// Set Booleans
var playedLast = false
var aiLost = false

override func didMoveToView(view: SKView) {
    otherElements()
    positionButtons()
    setText()
    jellyBean()
    self.targetValue = 21
    self.currentValue = 0
    self.levelValue = 1
    self.jellyBeanValue = Int()
}

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    let touch = touches 
    let location = touch.first!.locationInNode(self)
    let node = self.nodeAtPoint(location)

    if (node.name == "buttonOne") {
        if !playedLast {
            currentValue++
            playerID = 1
            hasTargetReached()
            self.currentNumber.text = String(currentValue)
            print("You increased the value to " + String(currentValue))
            playedLast = true
            self.turnLabel.text = "AI Turn"
            delay(1) {
                self.playerAI()
            }
        }
    } else if (node.name == "buttonTwo") {
        if !playedLast {
            currentValue+=2
            playerID = 1
            hasTargetReached()
            self.currentNumber.text = String(currentValue)
            print("You increased the value to " + String(currentValue))
            playedLast = true
            self.turnLabel.text = "AI Turn"
            delay(1) {
                self.playerAI()
            }
        }
    } else if (node.name == "buttonThree") {
        if !playedLast {
            currentValue+=3
            playerID = 1
            hasTargetReached()
            self.currentNumber.text = String(currentValue)
            print("You increased the value to " + String(currentValue))
            playedLast = true
            self.turnLabel.text = "AI Turn"
            delay(1) {
                self.playerAI()
            }
        }
    } else if (node.name == "menuButton") {
        if let view = self.view {
            let scene = startScene(size: self.size)
            scene.scaleMode = .AspectFill
            view.presentScene(scene)
        }
    }

}

override func update(currentTime: CFTimeInterval) {
    /* Called before each frame is rendered */
    self.currentNumber.text = String(currentValue)
    self.levelNumber.text = "Level: " + String(levelValue)
    self.targetNumber.text = "Target: " + String(targetValue)
    self.beanNumber.text = String(jellyBeanValue)

}






func playerAI() {
    if !(currentValue >= (targetValue)-4) {
        currentValue+=Int(arc4random() % 3) + 1
        playerID = 2
        hasTargetReached()
        self.currentNumber.text = String(currentValue)
        print("AI increased the value to " + String(currentValue))
        playedLast = false
        self.turnLabel.text = "Your Turn"
    } else if (currentValue == (targetValue)-4) {
        currentValue+=3
        playerID = 2
        hasTargetReached()
        self.currentNumber.text = String(currentValue)
        print("AI increased the value to " + String(currentValue))
        playedLast = false
        self.turnLabel.text = "Your Turn"
    } else if (currentValue >= (targetValue)-3) {
        currentValue+=2
        playerID = 2
        hasTargetReached()
        self.currentNumber.text = String(currentValue)
        print("AI increased the value to " + String(currentValue))
        playedLast = false
        self.turnLabel.text = "Your Turn"
    } else if (currentValue >= (targetValue)-2) {
        currentValue+=1
        playerID = 2
        hasTargetReached()
        self.currentNumber.text = String(currentValue)
        print("AI increased the value to " + String(currentValue))
        playedLast = false
        self.turnLabel.text = "Your Turn"
    } else if (currentValue >= (targetValue)-1) {
        currentValue+=1
        playerID = 2
        hasTargetReached()
        self.currentNumber.text = String(currentValue)
        print("AI increased the value to " + String(currentValue))
        playedLast = false
        self.turnLabel.text = "Your Turn"
    }
}

// End Game

func endGame() {
    // save jellybeanvalue
    self.targetValue = 21
    self.currentValue = 0
    self.levelValue = 1
    self.levelNumber.text = "Level: " + String(levelValue)
    self.targetNumber.text = "Target: " + String(targetValue)
    self.turnLabel.text = "Your Turn"
    playedLast = false
    print("The game has been reset, Level " + String(levelValue))
}


// Delay AIs turn to play

func delay(delay:Double, closure:()->()) {
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), closure)
}

// Level Up, increase Jelly Bean total, increase the targetValue

func incrementLevel() {
    currentValue = 0
    levelValue++
    targetValue+=5
    jellyBeanValue+=10
    self.beanNumber.text = String(jellyBeanValue)
    self.currentNumber.text = String(currentValue)
    self.levelNumber.text = "Level: " + String(levelValue)
    self.targetNumber.text = "Target: " + String(targetValue)
    playedLast = false
    print("The Target Value is now " + String(targetValue) + " it is now Level " + String(levelValue))
}


// Check to see if the targetValue has been reached.

func hasTargetReached() {
    if (currentValue >= targetValue) {
        whoLost()
    }
}

// Find out who lost using the playerID

func whoLost() {
    if (playerID == 1) {
        aiLost = false
        print("Target Value has been reached by the player with the ID " + String(playerID) + " of whom lost the game. Game Over!")
        endGame()
    } else if (playerID == 2) {
        aiLost = true
        print("Target Value has been reached by the player with the ID " + String(playerID) + " of whom lost the game.")
        incrementLevel()
        playedLast = false
    }
}

// Position Decorative Elements

func otherElements() {
    backgroundColor = SKColor.whiteColor()
    header.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 8 * 7)
    header.size = CGSize(width: self.frame.width, height: self.frame.height / 4)
    header.zPosition = -1
    self.addChild(header)
}

// Position Buttons

func positionButtons() {
    buttonOne.position = CGPoint(x: self.frame.width / 4 - buttonOne.size.width / 3, y: self.frame.height / 2)
    buttonOne.size = CGSize(width: self.frame.width / 4, height: self.frame.width / 4)
    buttonOne.name = "buttonOne"

    buttonTwo.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 2)
    buttonTwo.size = CGSize(width: self.frame.width / 4, height: self.frame.width / 4)
    buttonTwo.name = "buttonTwo"

    buttonThree.position = CGPoint(x: self.frame.width / 4 * 3 + buttonThree.size.width / 3, y: self.frame.height / 2)
    buttonThree.size = CGSize(width: self.frame.width / 4, height: self.frame.width / 4)
    buttonThree.name = "buttonThree"

    menuButton.position = CGPoint(x: menuButton.size.width / 16 * 9, y: menuButton.size.height / 2 + menuButton.size.width / 16)
    menuButton.size = CGSize(width: self.frame.width / 5 * 2, height: menuButton.size.width / 3)
    menuButton.name = "menuButton"

    self.addChild(buttonOne)
    self.addChild(buttonTwo)
    self.addChild(buttonThree)
    self.addChild(menuButton)


}

// Position & Set Text

func setText() {
    currentNumber.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 6 * 4)
    currentNumber.text = String(currentValue)
    currentNumber.fontName = ("Fourfivesixseveneight")
    currentNumber.fontColor = SKColor.blackColor()
    currentNumber.fontSize = 400
    self.addChild(currentNumber)
    levelNumber.position = CGPoint(x: 50, y: self.frame.height / 16 * 15)
    levelNumber.text = ("Level: " + String(levelValue))
    levelNumber.fontName = ("Fourfivesixseveneight")
    levelNumber.fontColor = SKColor.whiteColor()
    levelNumber.fontSize = 100
    levelNumber.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.Left
    self.addChild(levelNumber)
    targetNumber.position = CGPoint(x: self.frame.width - 50, y: self.frame.height / 16 * 15)
    targetNumber.text = ("Target: " + String(targetValue))
    targetNumber.fontName = ("Fourfivesixseveneight")
    targetNumber.fontColor = SKColor.whiteColor()
    targetNumber.fontSize = 100
    targetNumber.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.Right
    self.addChild(targetNumber)
    turnLabel.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 3)
    turnLabel.text = ("Your Turn")
    turnLabel.fontName = ("Fourfivesixseveneight")
    turnLabel.fontColor = SKColor.blackColor()
    turnLabel.fontSize = 100
    self.addChild(turnLabel)
}


// Set Jelly Beans

func jellyBean() {
    jellyBeanImg.position = CGPoint(x: self.frame.width / 16 * 15, y: menuButton.size.height / 2 + menuButton.size.width / 16)
    jellyBeanImg.size = CGSize(width: self.frame.width / 8, height: self.frame.width / 8)
    self.addChild(jellyBeanImg)
    beanNumber.position = CGPoint(x: self.frame.width - jellyBeanImg.size.width, y: jellyBeanImg.size.height / 2)
    beanNumber.text = String(jellyBeanValue)
    beanNumber.fontName = ("Fourfivesixseveneight")
    beanNumber.fontColor = SKColor.blackColor()
    beanNumber.fontSize = 80
    beanNumber.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.Right
    self.addChild(beanNumber)
}

}

currently the endGame() function only resets the game, in the future it will take you to gameover scene. i hope you can help and if you need any more information please do not be afraid to ask.

Upvotes: 2

Views: 664

Answers (1)

Luca Angeletti
Luca Angeletti

Reputation: 59496

NSUserDefaults is the right tool for saving game score. It allows you to save data on persistent storage. So the next time the user runs your game, that data will be available.

Saving

var jellyBeanValue = 3
NSUserDefaults.standardUserDefaults().setInteger(3, forKey: "jellyBeanValue")

Loading (even after the app has been restarted)

var jellyBeanValue = NSUserDefaults.standardUserDefaults().integerForKey("jellyBeanValue")

More types

You can save/load other kinds of data with the following methods

func setBool(value: Bool, forKey defaultName: String)
func boolForKey(defaultName: String) -> Bool   

func setFloat(value: Float, forKey defaultName: String)
func floatForKey(defaultName: String) -> Float

func setDouble(value: Double, forKey defaultName: String)
func doubleForKey(defaultName: String) -> Double

Should you need to save instances of your custom classes you can use

func setObject(value: AnyObject?, forKey defaultName: String)
func objectForKey(defaultName: String) -> AnyObject?

but in this case please take a look at this.

iCloud

NSUserDefaults saves data on the persistent storage of your device. If you want to synch your data among all the Apple devices where the user is signed in with a specific AppleID you should use iCloud.

Upvotes: 2

Related Questions