使用 NSUserDefaults 在游戏中保存分数

save score in game with NSUserDefaults

我正在创建一个游戏,但是高分不想在gameScene中显示 分数是在 playScene 中计算的,并在一个名为 MLPointsLabel 的 class 中创建标签的名称和字体....等。

这是我的 playScene 代码 class :

//
//  PlayScene.swift
//  WalkRun
//
//  Created by naeim on 7/10/15.
//  Copyright (c) 2015 naeim. All rights reserved.
//

import Foundation
import SpriteKit

class PlayScene: SKScene, SKPhysicsContactDelegate{

    var ball = SKSpriteNode(imageNamed: "ball")
    var bg = SKSpriteNode(imageNamed: "bg")

    var wall = SKNode()
    var wallRight = SKNode()
    var ballSpeed = CGFloat()

    let ballCatogary:UInt32 = 0x1 << 0
    let objectsCatogary:UInt32 = 0x1 << 1
    let bottomWallCatogary:UInt32 = 0x1 << 3

    var endOfScreenRight = CGFloat()

    var gameOver = 0

    var movingObjects = SKNode()

    var score = 0

    var scoreLabel = SKLabelNode()

    var ballPositionY:CGFloat = 120

    var bigWall = SKSpriteNode()
    var tallWall = SKSpriteNode()

    var levelHardnes:Double = 0.6
    let reveal = SKTransition.flipHorizontalWithDuration(0.5)
    var num = 0

    var highScore = ""

    override func didMoveToView(view: SKView) {

        //create background
        createBackGround()
        self.physicsWorld.contactDelegate = self
        self.physicsWorld.gravity = CGVectorMake(-9,0)
        self.addChild(movingObjects)

        //creating the ball
        ball.position = CGPointMake(CGRectGetMidX(self.frame), ballPositionY)
        ball.physicsBody = SKPhysicsBody(circleOfRadius: self.ball.size.width / 2)
        ball.zPosition = 10
        ball.physicsBody?.categoryBitMask = ballCatogary
        ball.physicsBody?.collisionBitMask =  objectsCatogary
        ball.physicsBody?.contactTestBitMask =  objectsCatogary

        self.addChild(ball)

        //creating the wall of the left
        wall.position = CGPointMake(CGRectGetMinX(self.frame),CGRectGetMinY(self.frame))
        wall.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(2, self.frame.size.height * 2.0))
        wall.physicsBody?.dynamic = false
        wall.physicsBody?.categoryBitMask = objectsCatogary

        self.addChild(wall)

        //creating the wall of the right
        wallRight.position = CGPointMake(CGRectGetMaxX(self.frame), CGRectGetMinY(self.frame))
        wallRight.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(2, self.frame.size.height * 2.0))
        wallRight.physicsBody?.dynamic = false
        wallRight.physicsBody?.categoryBitMask = objectsCatogary

        self.addChild(wallRight)

        //creating the label
        scoreLabel.fontName = "Helvetica"
        scoreLabel.fontSize = 60
        scoreLabel.text = "0"
        scoreLabel.zPosition = 8
        scoreLabel.name = "pointsLabel"
        scoreLabel.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)  )
        self.addChild(scoreLabel)

        //bottom wall
        var bottomWall = SKNode()
        bottomWall.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMinY(self.frame) + ball.size.width * 1.5 )
        bottomWall.physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(self.frame.size.width , 1))
        bottomWall.physicsBody?.dynamic = false
        bottomWall.physicsBody?.affectedByGravity = false
        bottomWall.physicsBody?.categoryBitMask = bottomWallCatogary
        bottomWall.physicsBody?.collisionBitMask = objectsCatogary
        bottomWall.physicsBody?.contactTestBitMask = objectsCatogary

        loadHighScoew()

        self.addChild(bottomWall)

        var timer = NSTimer.scheduledTimerWithTimeInterval(levelHardnes, target: self, selector: Selector("randObject"), userInfo: nil, repeats: true)

    }

    func loadHighScoew(){
        let defaults = NSUserDefaults.standardUserDefaults()
         let highscoreLabel = childNodeWithName("highscoreLabel") as? MLPointLabel
        highscoreLabel?.setTo(defaults.integerForKey("highscore"))
    }

    func createBackGround(){

        bg.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
        bg.size.width = self.frame.size.width
        bg.size.height = self.frame.size.height
        self.addChild(bg)
    }

    func increaseScore(){
        score++
        println(score)
        scoreLabel.text = "\(score)"

    }

    //function to randomly choose which object

    func randObject(){
        if gameOver == 0{
        var rand = arc4random_uniform(6)+1
        switch(rand){

        case 1:
            leftObject()

        case 2:
            middleObject()

        case 3:
            rightObject()

        case 4:
            LeftAndMiddleObject()

        case 5:
            rightAndLeftObject()

        case 6:
            rightAndMiddleObject()

        default:
            println("error !! non a number other than 0, 1, 2 has been choosen .")

            }

        }
    }

    //function that creates a Bigwall
    func createBigWall(PositionX:CGFloat , PositionY:CGFloat){
        bigWall = SKSpriteNode(imageNamed: "shortwall")
        bigWall.position = CGPointMake(PositionX, PositionY)
        bigWall.physicsBody = SKPhysicsBody(rectangleOfSize: self.bigWall.size)
        bigWall.physicsBody?.dynamic = true
        bigWall.physicsBody?.affectedByGravity = false
        bigWall.physicsBody?.categoryBitMask = objectsCatogary
        bigWall.physicsBody?.collisionBitMask = ballCatogary
        bigWall.physicsBody?.contactTestBitMask = ballCatogary
        bigWall.physicsBody?.collisionBitMask = 0
        bigWall.physicsBody?.contactTestBitMask = bottomWallCatogary
        bigWall.zPosition = 12

        var moveObjects = SKAction.moveByX(0, y: -self.frame.size.height * 2, duration: NSTimeInterval(self.frame.size.height / 100))
        var removeObjects = SKAction.removeFromParent()
        var moveAndRemoveObjects = SKAction.sequence([moveObjects,removeObjects])
        bigWall.runAction(moveAndRemoveObjects)
        movingObjects.addChild(bigWall)

    }
    //function that creates a Tallwall
    func createTallWall(PositionX:CGFloat , PositionY:CGFloat ){
        tallWall = SKSpriteNode(imageNamed: "tallwall")
        tallWall.position = CGPointMake(PositionX, PositionY)
        tallWall.physicsBody = SKPhysicsBody(rectangleOfSize: self.tallWall.size)
        tallWall.physicsBody?.dynamic = true
        tallWall.physicsBody?.affectedByGravity = false
        tallWall.physicsBody?.categoryBitMask = objectsCatogary
        tallWall.physicsBody?.collisionBitMask = ballCatogary
        tallWall.physicsBody?.contactTestBitMask = ballCatogary
        tallWall.physicsBody?.collisionBitMask = 0
        tallWall.physicsBody?.contactTestBitMask = bottomWallCatogary
        tallWall.zPosition = 12
        var moveObjects = SKAction.moveByX(0, y: -self.frame.size.height * 2, duration: NSTimeInterval(self.frame.size.height / 100))
        var removeObjects = SKAction.removeFromParent()
        var moveAndRemoveObjects = SKAction.sequence([moveObjects,removeObjects])
        tallWall.runAction(moveAndRemoveObjects)
        movingObjects.addChild(tallWall)

    }

    //function to create the left objects

    func leftObject(){
        var rand = arc4random_uniform(2) + 1
        if rand == 1
        {
           createBigWall(CGRectGetMinX(self.frame) + 30, PositionY: CGRectGetMaxY(self.frame))

        }
        else
        {
            createTallWall(CGRectGetMinX(self.frame) - 60, PositionY: CGRectGetMaxY(self.frame))
        }

    }

    //function to create the middle objects

    func middleObject(){

        var rand = arc4random_uniform(2) + 1
        if rand == 1
        {
            createBigWall(CGRectGetMidX(self.frame) , PositionY: CGRectGetMaxY(self.frame))

        }
        else
        {

            createTallWall(CGRectGetMidX(self.frame), PositionY: CGRectGetMaxY(self.frame))

        }

    }

    //function to create the right objects

    func rightObject(){
        var rand = arc4random_uniform(2) + 1
        if rand == 1
        {
            createBigWall(CGRectGetMaxX(self.frame) - 30, PositionY: CGRectGetMaxY(self.frame))

        }
        else
        {
      createTallWall(CGRectGetMaxX(self.frame) - 60, PositionY: CGRectGetMaxY(self.frame))

        }

    }

    //function to create a right and left object

    func rightAndLeftObject(){

        var rand = arc4random_uniform(2) + 1
        if rand == 1
        {
            createBigWall(CGRectGetMaxX(self.frame) - 30 , PositionY: CGRectGetMaxY(self.frame))
            createTallWall(CGRectGetMinX(self.frame) + 60, PositionY: CGRectGetMaxY(self.frame))
        }
        else
        {

            createBigWall(CGRectGetMinX(self.frame) - 30, PositionY: CGRectGetMaxY(self.frame))
            createTallWall(CGRectGetMaxX(self.frame) + 60, PositionY: CGRectGetMaxY(self.frame))

                    }

    }

    func rightAndMiddleObject(){

        var rand = arc4random_uniform(2) + 1
        if rand == 1
        {
            createBigWall(CGRectGetMidX(self.frame) - 30, PositionY: CGRectGetMaxY(self.frame))
            createTallWall(CGRectGetMaxX(self.frame) + 60, PositionY: CGRectGetMaxY(self.frame))
        }
        else
        {
            createBigWall(CGRectGetMaxX(self.frame) - 30, PositionY: CGRectGetMaxY(self.frame))
            createTallWall(CGRectGetMinX(self.frame) + 60, PositionY: CGRectGetMaxY(self.frame))
        }

    }

    func LeftAndMiddleObject(){

        var rand = arc4random_uniform(2) + 1
        if rand == 1
        {
            createBigWall(CGRectGetMinX(self.frame) - 30, PositionY: CGRectGetMaxY(self.frame))
            createTallWall(CGRectGetMidX(self.frame) + 60, PositionY: CGRectGetMaxY(self.frame))
        }
        else
        {
            createBigWall(CGRectGetMidX(self.frame) - 30, PositionY: CGRectGetMaxY(self.frame))
            createTallWall(CGRectGetMinX(self.frame) + 60, PositionY: CGRectGetMaxY(self.frame))
        }

    }

    func sendHighScore()->String{
        return highScore
    }

    func gameOverDisplay(){
        gameOver = 1
        movingObjects.speed = 0

        if num < score{

            num = score
            highScore = "\(num)"
            let defaults = NSUserDefaults.standardUserDefaults()
            defaults.setInteger(num, forKey: "highscore")
        }

        //creating the game Over label
        let gameOverScene = GameOverScene(size: self.size, won: false)
        self.view?.presentScene(gameOverScene, transition: reveal)

    }

    func didBeginContact(contact: SKPhysicsContact) {

        // 1. Create local variables for two physics bodies
        var firstBody: SKPhysicsBody
        var secondBody: SKPhysicsBody

        // 2. Assign the two physics bodies so that the one with the lower category is always stored in firstBody
        if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
            firstBody = contact.bodyA
            secondBody = contact.bodyB
        } else {
            firstBody = contact.bodyB
            secondBody = contact.bodyA
        }

        // 3. react to the contact between ball and bottom
        if firstBody.categoryBitMask == ballCatogary && secondBody.categoryBitMask == objectsCatogary {

            gameOverDisplay()

        }
        else if firstBody.categoryBitMask == objectsCatogary || secondBody.categoryBitMask == bottomWallCatogary{
            increaseScore()
        }
    }

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        if gameOver == 0 {

        ball.physicsBody?.velocity = CGVectorMake(0, 0)
        ball.physicsBody?.applyImpulse(CGVectorMake(50,0))

        }

    }

    override func update(currentTime: NSTimeInterval) {

        switch(score){
        case 25:
            levelHardnes = 0.5
            ballPositionY += 55
        case 50:
            levelHardnes = 0.4
            ballPositionY += 55
        case 100:
            levelHardnes = 0.3
            ballPositionY += 55
        case 250:
            levelHardnes = 0.2
            ballPositionY += 55
        case 300:

            ballPositionY += 55
        case 400:

            ballPositionY += 55
        default:
            levelHardnes = 0.1
        }

    }
}

这是我的 GameScene 代码:

//
//  GameScene.swift
//  WalkRun
//
//  Created by naeim on 7/10/15.
//  Copyright (c) 2015 naeim. All rights reserved.
//

import SpriteKit

class GameScene: SKScene {
    let playButton = SKSpriteNode(imageNamed: "play")
    let bg = SKSpriteNode(imageNamed: "bg")
    let labelIntro = SKLabelNode()
    let playscene = PlayScene()

    override func didMoveToView(view: SKView) {
        playButton.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
        playButton.zPosition = 3
        self.addChild(playButton)
        createBackGround()
        labelMaker()

        playscene.loadHighScoew()

        var highScorenum = playscene.sendHighScore()

        var highScoreLabel = SKLabelNode()
        highScoreLabel.text = "High score : " + highScorenum
        highScoreLabel.fontSize = 40
        highScoreLabel.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMaxY(self.frame) - 220)
        highScoreLabel.fontName = "Chalkduster"
        highScoreLabel.zPosition = 3
        self.addChild(highScoreLabel)

    }

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        for touch: AnyObject in touches{
            let location = touch.locationInNode(self)
            if self.nodeAtPoint(location) == self.playButton{
                var scene = PlayScene(size: self.size)
                let sKview = self.view
                sKview?.ignoresSiblingOrder = true
                scene.scaleMode = .ResizeFill
                sKview?.presentScene(scene)
            }
        }
    }


    func labelMaker(){
        labelIntro.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMaxY(self.frame) - 150)
        labelIntro.fontName = "Chalkduster"
        labelIntro.fontColor = UIColor(hex:000000)
        labelIntro.text = "Wall climp"
        labelIntro.fontSize = 60
        labelIntro.zPosition = 3
        self.addChild(labelIntro)
    }

    func createBackGround(){

        bg.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
        bg.size.width = self.frame.size.width
        bg.size.height = self.frame.size.height
        bg.zPosition = 2
        self.addChild(bg)
    }

    override func update(currentTime: CFTimeInterval) {
    /* Called before each frame is rendered */

    }
}

这是我的 MLPointLabel class:

//
//  MLPointsLabel.swift
//  WalkRun
//
//  Created by naeim on 7/16/15.
//  Copyright (c) 2015 naeim. All rights reserved.
//

import Foundation
import UIKIt
import SpriteKit

class MLPointLabel:SKLabelNode {

     var number = 0
    var playScene = PlayScene()
    init(num: Int){
        super.init()
        name = "highscore"
        fontColor = UIColor.whiteColor()
        fontName = "Chalkduster"
        fontSize = 40.0
        zPosition = 3
        var number = num
        text = " High Score :" + "\(num)"

    }

    func setTo(num:Int){
        self.number = num
        text = "\(self.number)"
    }

    func increment(){
        number++
        text = "\(number)"
    }

    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

我真的想不通为什么,当我运行玩游戏时,没有给我任何错误,反而没有保存高分

尝试

let defaults = NSUserDefaults.standardUserDefaults()
defaults.setValue(num, forKey: "highscore")

并且当您在 GameScene 中检索您的高分时,最好直接从 NSUserDefaults 中检索它,例如

let defaults = NSUserDefaults.standardUserDefaults()
var highScorenum = defaults.valueForKey("highscore")!.stringValue

希望这对您有所帮助!

这里我对你的代码做了一些修改。

GameScene.swift

//read your score this way
func addHighScoreLbl() {

    let highScorenum = NSUserDefaults.standardUserDefaults().integerForKey("highscore")
    var highScoreLabel = SKLabelNode()
    highScoreLabel.text = "High score : \(highScorenum)"
    highScoreLabel.fontSize = 40
    highScoreLabel.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMaxY(self.frame) - 220)
    highScoreLabel.fontName = "Chalkduster"
    highScoreLabel.zPosition = 3
    self.addChild(highScoreLabel)
}

PlayScene.swift

func didBeginContact(contact: SKPhysicsContact) {


    // 1. Create local variables for two physics bodies
    var firstBody: SKPhysicsBody
    var secondBody: SKPhysicsBody

    // 2. Assign the two physics bodies so that the one with the lower category is always stored in firstBody
    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
        firstBody = contact.bodyA
        secondBody = contact.bodyB
    } else {
        firstBody = contact.bodyB
        secondBody = contact.bodyA
    }

    // 3. react to the contact between ball and bottom
    if firstBody.categoryBitMask == ballCatogary && secondBody.categoryBitMask == objectsCatogary {

            let gameOverScene = GameOverScene(size: self.size, won: false)
            self.view?.presentScene(gameOverScene, transition: reveal)

    }
    else if firstBody.categoryBitMask == objectsCatogary || secondBody.categoryBitMask == bottomWallCatogary{

        score++

        if score > highScore {
            //Set your highscore this way.
            NSUserDefaults.standardUserDefaults().setInteger(score, forKey: "highscore")
        }
        scoreLabel.text = "\(score)"
    }
}