sprite kit tutorial GameViewController中的unarchiveFromFile方法是什麼?




xcode game教學 (2)

當我試圖在Swift中添加不同的場景時,我遇到了unarchiveFromFile方法。 這個方法的問題是它只能用於GameScene類。 如果你從中調用它

extension SKNode {
    class func unarchiveFromFile(file : NSString) -> SKNode? {
        if let path = NSBundle.mainBundle().pathForResource(file, ofType: "sks") {
            var sceneData = NSData.dataWithContentsOfFile(path, options: .DataReadingMappedIfSafe, error: nil)
            var archiver = NSKeyedUnarchiver(forReadingWithData: sceneData)

            archiver.setClass(self.classForKeyedUnarchiver(), forClassName: "SKScene")
            let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as GameScene 
            archiver.finishDecoding()
            return scene
        } else {
            return nil
        }
    }
}

class GameViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
             let skView = self.view as SKView
             skView.ignoresSiblingOrder = true
             skView.presentScene(scene)
        }
        // This won't work for MenuScene.unarchiveFromFile("MenuScene") as? MenuScene
        // nor MenuScene.unarchiveFromFile("MenuScene") as? GameScene

為了能夠和其他SKScenes一起工作,我把所有出現的GameScene變成了SKScene。 雖然它現在可以與其他SKScene類一起工作,但我仍然不明白它是什麼。

這是什麼方法? 我應該保留它嗎?


從0x141E的註釋開始,您可以將unarchiveFromFile方法更改為使用泛型,以便您可以將其用於不同的SKS或SKScene類:

extension SKNode {
    class func unarchiveFromFile<T:SKScene>(file : NSString) -> T? {
        if let path = NSBundle.mainBundle().pathForResource(file, ofType: "sks") {
            var sceneData = NSData(contentsOfFile: path, options: .DataReadingMappedIfSafe, error: nil)!
            var archiver = NSKeyedUnarchiver(forReadingWithData: sceneData)

            archiver.setClass(self.classForKeyedUnarchiver(), forClassName: "SKScene")
            let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as T
            archiver.finishDecoding()
            return scene
        } else {
            return nil
        }
    }
}

只要調用它的方式相同,但是在那裡你想要的不同的場景內容,它應該工作正常

if let scene = GameScene.unarchiveFromFile("Level1Scene") as? GameScene {
...

if let scene = GameScene.unarchiveFromFile("Level2Scene") as? GameScene {
...

我沒有使用Xcode 6,但是這裡是我的理解(有人可能糾正我或解釋):

這是您的應用程序如何利用GameScene(或任何SKScene )的佈局數據等。 如果你點擊Project Navigator面板中的GameScene.sks文件,你會得到一個GameScene的可視化編輯器。

如果你想要使用這個佈局數據,你可以使用這個方法。 您可以在場景編輯器中直觀地佈局GameScene,而無需編碼位置,設置等。