2015-05-31 15 views
5

Tôi đang cố gắng tạo trò chơi nhanh chóng kit sprite đầu tiên của mình và tôi có dữ liệu trò chơi của mình hoạt động bằng cách sử dụng nsuserdefaults. Tôi muốn làm cho nó an toàn hơn vì vậy tôi đang cố gắng chuyển sang NSCoding, nhưng không có gì tôi tìm thấy trực tuyến đã giúp tôi hoàn toàn và đã nhầm lẫn tôi (vì vậy xin lỗi nếu câu trả lời đã tồn tại, tôi có thể đã xem xét nó và không 't có thể hiểu)Thay đổi từ NSUserDefaults thành NSCoding

Đây là lớp GameState tôi:.

class GameState { 
var score: Int 
var highScore: Int 
var stars: Int 
var sound: Bool 
var carType: Int 
var xSize: Double 
var ySize: Double 
var gameOver: Bool 

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

    return Singleton.instance 
} 

init() { 
    // Init 
    score = 0 
    highScore = 0 
    stars = 0 
    carType = 1 
    sound = true 
    xSize = 1 
    ySize = 1 
    gameOver = false 

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

    highScore = defaults.integerForKey("highScore") 
    stars = defaults.integerForKey("stars") 
    sound = defaults.boolForKey("sound") 
    carType = defaults.integerForKey("carType") 
    xSize = defaults.doubleForKey("xSize") 
    ySize = defaults.doubleForKey("ySize") 
    gameOver = defaults.boolForKey("gameOver") 
} 


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(stars, forKey: "stars") 
    defaults.setBool(sound, forKey: "sound") 
    defaults.setInteger(carType, forKey: "carType") 
    defaults.setDouble(xSize, forKey: "xSize") 
    defaults.setDouble(ySize, forKey: "ySize") 
    defaults.setBool(gameOver, forKey: "gameOver") 
    NSUserDefaults.standardUserDefaults().synchronize() 
} } 

và tôi lưu và tải dữ liệu trong các lớp học khác của tôi sử dụng:

GameState.sharedInstance.***** 

Làm thế nào tôi sẽ đi về việc thay đổi này thế nào để thực hiện NSCoding và sau đó tải và lưu dữ liệu từ các lớp khác? Cảm ơn.

Trả lời

2

Lớp bạn muốn lưu phải tuân theo giao thức NSCoding và triển khai required init(coder aDecoder: NSCoder)func encodeWithCoder(aCoder: NSCoder).

Dưới đây là một ví dụ đơn giản:

class GameState: NSObject, NSCoding { 

    var score: Int? 
    var gameOver: Bool? 

    init(score: Int, gameOver: Bool) { 
     super.init() 
     self.score = score 
     self.gameOver = gameOver 
    } 

    required init(coder aDecoder: NSCoder) { 
     self.score = aDecoder.decodeObjectForKey("score") as? Int 
     self.gameOver = aDecoder.decodeObjectForKey("gameOver") as? Bool 
    } 

    func encodeWithCoder(aCoder: NSCoder) { 
     aCoder.encodeObject(self.score, forKey: "score") 
     aCoder.encodeObject(self.gameOver, forKey: "gameOver") 
    } 

} 

let myGameState = GameState(score: 42, gameOver: true) 

Sau đó, bạn có thể sử dụng NSKeyedArchiverNSKeyedUnarchiver, ví dụ như trong appdelegate, để tiết kiệm và tải đối tượng của bạn dưới dạng dữ liệu:

func applicationWillTerminate(aNotification: NSNotification) { 
    NSKeyedArchiver.archiveRootObject(myGameState, toFile: "a/file/path") 
} 

func applicationDidFinishLaunching(aNotification: NSNotification) { 
    if let data = NSKeyedUnarchiver.unarchiveObjectWithFile("a/file/path") as? GameState { 
     myGameState = data 
    } 
} 
+0

Cảm ơn trả lời của bạn, chỉ một vài câu hỏi: là 'cho phép myGameState ...' những gì bạn sử dụng thay vì lớp init() ban đầu để thêm giá trị cho mỗi biến? làm cách nào để cập nhật trò chơi từ các lớp khác? (để cập nhật điểm số và âm thanh, v.v.) cảm ơn – AEkon

+0

Bạn được chào đón. Nó chỉ là một init với các tham số tôi đã làm cho ví dụ của tôi, bạn không cần phải thay đổi của bạn. Bạn chỉ phải thực hiện "bắt buộc" một và đảm bảo tất cả các thuộc tính bạn muốn tải được khai báo ở đây. – Moritz

+0

oh alright bệnh cố gắng mà cảm ơn một lần nữa! cho toFile trong appdelegate, làm thế nào tôi có thể lưu nó vào điện thoại đang được sử dụng? cảm ơn – AEkon

Các vấn đề liên quan