在不同场景中使用变量

问题描述:

在我的GameScene中,我有一个名为“score”的变量,我想在MenuScene中使用它来显示最新的分数。我已经用UserDefaults试过了,但是我并没有真正理解它,它不起作用。有人可以告诉我如何声明分数变量,以便我可以在其他场景中使用它,如果有人能够告诉我如何保存变量以便我可以保存高分,这也会很好。在不同场景中使用变量

我已经试过这样:

GameScene:

let userDefaults = UserDefaults.standard // Before didMove func 
UserDefaults.setValue(score, forKey: "Score") // in gameOver func 

MenuScene:

var score = SKLabelNode() 
var scoreNumber = UserDefaults.standard.integer(forKey: "Score") 

如果我运行它加载MenuScene,我可以按下播放和游戏它去到GameScene。如果我在GameScene中死亡,则游戏崩溃,并且出现此错误:“由于未捕获的异常'NSUnknownKeyException'导致应用程序终止,原因:'[setValue:forUndefinedKey:]:此类不是关键值编码兼容的关键分数''

+0

UserDefaults应该工作。显示你的尝试,你很可能会得到你的答案。或者只是使用搜索,关于该主题有很多答案。 – Whirlwind

+0

我用score = UserDefaults.standard score.set(“String”,forKey“Score”) 但正如我所说我并不真正了解它 –

如果您正确使用用户默认值,您应该可以读取和写入任何对象,因为UserDefaults.standard是一个单例。沿着这些线路的东西应该工作:

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() 
    } 
} 

说你可以有一个更加美好的架构实现ScoreManager对象并注入它(而不必在一个单独的硬相关)到您的游戏场景。

更新: 刚刚看到您的代码段。您需要使用set,而不是setValuesetValue不是UserDefaults的一种方法,但是是KVO的NSObject的一种方法。

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.

这不是你在找什么;)

你打电话set请确保调用synchronize也可以肯定,该值立即被存储后也。

我希望这会有所帮助。

+0

我知道在GameScene的GameOver函数中有“UserDefaults.setValue评分,forKey:“得分”)“和在MenuScene”var score = UserDefaults.standard.integer(forKey:“Score”)“但是当我测试游戏时,我第一次从GameScene切换到MenuScene,我得到这个错误:“终止应用程序,由于未捕获异常'NSUnknownKeyException',原因:'[ setValue:forUndefinedKey:]:此类不是关键值编码兼容的关键分数。我做错了什么? –

+0

你能发布你的代码片段吗? – tanzolone

+0

编辑我的问题 –

您可以将var gameScore从全局移除,即将其从GameScene中移除,并在import SpriteKitclass GameScene之间移动以使其具有通用性。之后,您可以像其他人所建议的那样使用NSUserDefault

UPDATE

好了,所以我GAMEOVER的场景,我通常做的类

let defaults = NSUserDefaults() 
var highScoreNumber = defaults.integerForKey("highScoreSaved") 

If gameScore > highScoreNumber{ 
highScoreNumber = gameScore 
defaults.setInteger(highScoreNumber, forKey: "highScoreSaved") 
    } 

你可以做这在你的MenuScene内,而不是像这样。

+0

问题是,我不知道如何使用UserDefault,我也无法在网上找到任何东西。 –

如果您想在差异视图控制器中使用动态变量。并一直使用它。你在Appdelegate中创建。

在你的AppDelegate。swift

var yourVariableName: Any = "Value" 

当你想使用它或改变它。你

let app: AppDelegate = UIApplication.shared.delegate as! AppDelegate 
    print(app.youVariableName) 

如果你想观察变量值的变化并做一些动作。你设置了一个didSet函数。

var yourVariableName: Any = "VALUE" {didSet{observeValueChangeFunction()}} 
func didSet{observeValueChangeFunction() { 
    print("New value: \(yourVariableName)") 
} 

我不认为你应该使用UserDefaults要做到这一点,

第一个原因,我想问问你,如果有人关闭应用程序,也许他们杀死,当他们在玩的应用程序,你如何与分数达成协议?

当然,你不应该保持这个分数,对不对?或者您应该缓存游戏的所有数据,然后当玩家再次进入游戏时,您可以回到应用程序关闭时的状态。但我认为这样做非常复杂。

所以我觉得你应该把这个分数放在全局或者更容易控制这个只是将GameScene的分数传递给也许叫做ResultScene

我想你的游戏有这些情景: LoginSceneMapSceneGameSceneResultSceneRankScene

,所以你只需要使用在GameScene并实时ResultScene的得分,所以你才这样做的GameScene

var score : Int/CGFloat  = 0; 
func enterFrame(){ 
    //if they got the goal, then 
    // score = score + 1 or much more; 
} 

func gameOver(){ 
    let resultScene = ResultScene(score: score); 
    // or you could just create the empty ResultScene, and pass the score via a public func of the ResultScene 
} 

然后你可以在ResultScene中显示得分。

如果你只是做无服务器的游戏,你应该保持比分进入UserDefaultsCoreDataSQLite等 那么你就可以显示有关history records一些场景的分数。