Я исследовал множество способов сохранения постоянных данных между сценами, NSUserdefaults, Global Structs, Dict и т. д., и, как и многие другие, это зависит от вашей игры и от того, как игра (IMO) будет развиваться со временем. Для моей ситуации у меня нет постоянной игровой сцены, где игровая логика вызывает увеличение сложности. У меня есть 13 игровых сцен, 7 из которых требуют голосов за эту сцену, 2 из которых должны отображать высокие голоса.
1.) Имея эти голоса, заполните каждую игровую сцену до высоких голосов, 2.) Сохранение этих голосов,
//пример в gameScene
var vote: Int = 0 {
didSet {
gameScore.text = "Votes: \(vote)"
}
Ошибка: при попытке получить данные счета из GameScene obj-C Error
Создал глобальную сцену: (здесь предлагалось много раз, там есть все, данные сцены, звуки и т. д. Не удается загрузить данные сцены при реализации NSObject, NSCoding. BaseScene
Не нравятся NSObject и NSCoding в объявление класса либо я понял это.
struct GlobalData {
//other Global Data
static let encodedData = "encodedData"
static let highVotes = "highVotes"
convenience required init?(coder decoder: NSCoder) {
self.init()
print("BaseScene convenience init")
// // Progress
highVotes = decoder.decodeIntegerForKey(GlobalData.highVotes)
}
// Mark: - Encode
override func encodeWithCoder(encoder: (NSCoder)) {
//Progress
encoder.encodeInteger(highVotes, forKey: GlobalData.highVotes)
Код ошибки на картинке. Мои сцены были преобразованы в строки, теперь они не будут взаимодействовать. Он утверждает, что хочет GameScene (кодер: GameScene) нет!!
/// Progress (not saved, no need for saving the score because of the highScore var. Still have here for global single access
var votes: Int = 0
/// Progress (saved)
var highVotes: Int = 0
case SceneType.GameScene:
sceneToLoad = GameScene(coder:GameScene) //nope
//Error cannot create a single element tuple with an element label.
следовал этому примеру: Параметры, отличные от USERDefaults
Думаю, я бы сослался на это, а не публиковал весь код.
моя цель состояла в том, чтобы реализовать эту возможность в одном глобальном файле вместо того, чтобы разбивать переменные. Любые предложения были бы полезны?? Если вам нужно больше кода, пожалуйста, спросите. Я изменил код, чтобы он соответствовал моему проекту, но он не работает. Смотрите фото Еще раз спасибо. (Пожалуйста, будьте нежны, LOL) На самом деле, мне просто нужно это сделать, у каждого свой путь, и я нанесла удар каждому из них.
import Foundation
class VoteData: NSObject, NSCoding {
static let sharedInstance = VoteData.loadInstance()
struct Key {
static let encodedData = "encodedData"
static let highVotes = "highVotes"
}
/// Defaults
private let defaults = NSUserDefaults.standardUserDefaults()
private let iCloudDefaults = NSUbiquitousKeyValueStore.defaultStore()
/// Progress (not saved, no need for saving the score because of the highScore
var votes: Int = 0
/// Progress (saved)
var highVotes: Int = 0
// Mark: Init
private override init() {
super.init()
print("VoteData init")
NSNotificationCenter.defaultCenter().addObserver(self, selector: "updateFromCloud", name: NSUbiquitousKeyValueStoreDidChangeExternallyNotification, object: iCloudDefaults)
iCloudDefaults.synchronize()
}
// MARK: - Convenience Init
convenience required init?(coder decoder: NSCoder) {
self.init()
print("GameData convenience init")
// Progress
highVotes = decoder.decodeIntegerForKey(Key.highVotes)
}
// Mark: - Encode
func encodeWithCoder(encoder: NSCoder) {
//Progress
encoder.encodeInteger(highVotes, forKey: Key.highVotes)
Сохранять
func save() {
if votes > highVotes {
highVotes = votes
}
saveLocally()
saveToCloud()
}
}
/// Load instance
private class func loadInstance() -> VoteData {
if let decodedData: AnyObject = NSUserDefaults.standardUserDefaults().objectForKey(Key.encodedData) {
print("Decoding Data")
let voteData = NSKeyedUnarchiver.unarchiveObjectWithData(decodedData as! NSData) as! VoteData
return voteData
} else {
print("No data, creating new")
return VoteData()
}
}
/// Save Locally
private func saveLocally() {
let encodedData = NSKeyedArchiver.archivedDataWithRootObject(self)
defaults.setObject(encodedData, forKey: Key.encodedData)
}
/// Save to ICLOUD
private func saveToCloud() {
print("Saving to iCloud")
// Highvotes
if (highVotes > iCloudDefaults.objectForKey(Key.highVotes) as? Int ?? Int()) {
iCloudDefaults.setObject(highVotes, forKey: Key.highVotes)
}
}
/// Update from ICLOUD
func updateFromCloud() {
print("Updating from iCloud")
// HighVotes
highVotes = max(highVotes, iCloudDefaults.objectForKey(Key.highVotes) as? Int ?? Int())
// Save
saveLocally()
}
}
РЕДАКТИРОВАТЬ*************
да, проще создавать глобальные переменные, и я с нетерпением жду возможности сделать это и собрать эти данные. Чего я не понял до того, как погрузился в кроличью нору, так это важной строки кода, которая продолжает показывать свое лицо:
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
let ScoreDefault = NSUserDefaults.standardUserDefaults()
let Score = ScoreDefault.valueForKey("Score") as! NSInteger
NSLog("\(Score)")
let HighscoreDefault = NSUserDefaults.standardUserDefaults()
Highscore = HighscoreDefault.valueForKey("Highscore") as! NSInteger
NSLog("\(Highscore)")
снова вызывая этот счет с помощью NSCoder !!! По мере того, как моя игра растет и становится больше, я могу стать очень изобретательным и реализовать некоторые из этих продуманных решений, я отслеживаю две переменные в моей игре в данный момент, поэтому нет необходимости усложнять ее.
Базовая сцена для значений, преобразованных в строки: Мои сцены, вызываемые по имени файла:
convenience init(string aString:NSString) {
fatalError("init(string:) has not been implemented")