使用 Swift 在 Sprite Kit 游戏中重置高分

Posted

技术标签:

【中文标题】使用 Swift 在 Sprite Kit 游戏中重置高分【英文标题】:Reset a high score in a Sprite Kit game using Swift 【发布时间】:2015-12-17 07:13:16 【问题描述】:

我正在尝试重置我在 Sprite Kit 游戏中的高分,但遇到了一些问题。

现在,我可以将 HUD 中的标签重置为零,但是当游戏再次开始时,标签中的分数会跳回到之前的位置,因为它们存储在 NSUserDefaults 中。

我正在像这样重置标签:

override func didMoveToView(view: SKView) 

   lblCoins.text = "0"
   lblScore.text = "0"

 

我正在尝试像这样重置 NSUserDefaults:

NSUserDefaults.standardUserDefaults().setInteger(0, forKey: "highScore")
NSUserDefaults.standardUserDefaults().setInteger(0, forKey: "coins")
NSUserDefaults.standardUserDefaults().synchronize()

我尝试在我的游戏中随处放置这段代码,但似乎无法重置分数。只有当我完全重置应用程序时,分数才会重置。

以下是我尝试放置的一些函数:

override func didMoveToView(view: SKView) 

   NSUserDefaults.standardUserDefaults().setInteger(0, forKey: "highScore")
   NSUserDefaults.standardUserDefaults().setInteger(0, forKey: "coins")
   NSUserDefaults.standardUserDefaults().synchronize()

在游戏结束时:

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) 

   ...

 case is GameOver:
    let newScene = GameScene(fileNamed:"GameScene")
    newScene!.scaleMode = .AspectFill
  let reveal = SKTransition.flipHorizontalWithDuration(0.5)
  self.view?.presentScene(newScene!, transition: reveal)

  self.saveHighScore("com.prismstudios.jumpingcarl.leaderboard", score: GameState.sharedInstance.highScore)

   NSUserDefaults.standardUserDefaults().setInteger(0, forKey: "highScore")
   NSUserDefaults.standardUserDefaults().setInteger(0, forKey: "coins")
   NSUserDefaults.standardUserDefaults().synchronize()

 default:
   break
 

这是我在 GameScene 中添加点的地方:

func didBeginContact(contact: SKPhysicsContact) 

  GameState.sharedInstance.highScore += 10
  lblScore.text = String(format: "%d", GameState.sharedInstance.highScore)

  GameState.sharedInstance.coins += 1
  lblCoins.text = String(format: "%d", GameState.sharedInstance.coins)

GameState 类:

class GameState 
   var score: Int
   var highScore: Int
   var coins: Int

   init() 
     // Init
     score = 0
     highScore = 0
     coins = 0

    // Load game state
    let defaults = NSUserDefaults.standardUserDefaults()

    highScore = defaults.integerForKey("highScore")
    coins = defaults.integerForKey("coins")
  

  func saveState() 
    // Update highScore if the current score is greater
    highScore = max(score, highScore)

    // Store in user defaults
    let defaults = NSUserDefaults.standardUserDefaults()
    defaults.setInteger(highScore, forKey: "highScore")
    defaults.setInteger(coins, forKey: "coins")
    NSUserDefaults.standardUserDefaults().synchronize()
  

  class var sharedInstance: GameState 
    struct Singleton 
        static let instance = GameState()
    

    return Singleton.instance
  

有人可以帮忙吗?

【问题讨论】:

saveHighScore 方法中有什么? @hannad 我做了一个要点:gist.github.com/lumierephoto/828848d37cf0ba892620 您确定正在调用重置 NSUserDefaults 的代码块吗?另外,分数是否显示在从那里检索到的标签中? 我不确定它是否被调用。我只知道 highScore 没有重置。 @Paul 高分不会重置,因为您没有覆盖它。你只是插入一个“新的”。 (我给你写了一个答案,也许对你有帮助。-我遇到了同样的问题,浪费了很多时间来解决这个问题) 【参考方案1】:

如果你想重置一切,试试这个:

    let defaults = `NSUserDefaults`.standardUserDefaults()
    let appDomain: NSString = NSBundle.mainBundle().bundleIdentifier!


    defaults.removePersistentDomainForName(appDomain as String)

如果你只是想重置你的高分,你必须选择正确的“一个”。如果你正在做这样的事情:

defaults.setValue(123, forKey: "Highscore")
defaults.synchronize()

然后

defaults.setValue(0, forKey: "Highscore")
defaults.synchronize()

你有类似数组的东西:

Highscore1 = defaults.objectForKey("Highscore")![0] as? Int //123
Highscore2 = defaults.objectForKey("Highscore")![1] as? Int //0

你只是在增加更多的高分......试试这样的事情:

 func resetHighscore()

        let defaults = `NSUserDefaults`.standardUserDefaults()

        defaults.removeObjectForKey("Highscore")
        defaults.setValue(0, forKey: "Highscore")
        defaults.synchronize()

    

【讨论】:

那么,我应该在 Sprite Kit 游戏的哪个位置运行 resetHighscore() 来重置 NSUserDefaults?我已经尝试过didMoveToViewGameOver 案例。还是不行。 @Paul just put this: NSUserDefaults.standardUserDefaults().setInteger(0, forKey: "highScore") NSUserDefaults.standardUserDefaults().setInteger(0, forKey: "coins") NSUserDefaults.standardUserDefaults().synchronize() with that: let defaults = NSUserDefaults.standardUserDefaults() defaults.removeObjectForKey("highScore") defaults.setValue(0, forKey: "highScore") defaults.synchronize() 如果它不起作用,您确定调用了 GameOver 案例吗? 你可以很容易地检查它是否被两个“打印”调用。重置 HighScore 之前打印一份,重置 ist 之后打印一份。 我更新了我的问题以包含我的 GameScene 和 GameState 相关代码。【参考方案2】:

好的,我想通了。

之后,我将分数发布到游戏中心,然后添加GameState.sharedInstance.highScore = 0

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) 

 switch gameState.currentState 

   ...

  case is GameOver:
    let newScene = GameScene(fileNamed:"GameScene")
    newScene!.scaleMode = .AspectFill
    let reveal = SKTransition.flipHorizontalWithDuration(0.5)
    self.view?.presentScene(newScene!, transition: reveal)

    // Save high score to Game Center
    self.saveHighScore("com.prismstudios.jumpingcarl.leaderboard", score: GameState.sharedInstance.highScore)

    // Reset score and coins collected back to zero
    GameState.sharedInstance.highScore = 0
    GameState.sharedInstance.coins = 0

    default:
    break
  

我不太确定为什么它会这样工作并且 NSUserDefaults 失败,但我知道这与我有一个 GameState 辅助类这一事实有关。

【讨论】:

以上是关于使用 Swift 在 Sprite Kit 游戏中重置高分的主要内容,如果未能解决你的问题,请参考以下文章

使用 Sprite Kit 和 Swift 在游戏中显示当前分数

如何使用 Swift 2(Xcode 7)在我的 Sprite Kit 游戏中为背景音乐设置静音按钮?

游戏中的三角学——Sprite Kit 和 Swift 教程

游戏中的三角学——Sprite Kit 和 Swift 教程

用Swift语言和Sprite Kit复制微信飞机大战游戏

Swift Sprite Kit 中的游戏中心