GameViewController中的unarchiveFromFile方法是什么?

时间:2014-08-24 02:27:05

标签: sprite-kit viewcontroller skscene

当我尝试在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课程一起使用,但我仍然不了解它是什么。

这种方法是什么用的?我应该保留吗?

2 个答案:

答案 0 :(得分:3)

我还没有使用Xcode 6,但这是我的理解(有人可能会纠正我或解释):

这就是你的应用程序如何利用GameScene(或任何SKScene)的布局数据等。如果单击Project Navigator面板中的GameScene.sks文件,您将获得GameScene的可视化编辑器。

如果您希望使用此布局数据,则可以使用该方法。您可以在场景编辑器中直观地布局GameScene,而无需编码位置,设置等。

答案 1 :(得分:2)

继续发出0x141E的评论后,您可以将unarchiveFromFile方法更改为使用generics,以便将其用于不同的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 {
...