Для чего нужен метод unarchiveFromFile в GameViewController?

Когда я пытался добавить разные сцены в свою игру на 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

Чтобы иметь возможность работать с другими SKScene, я изменил все вхождения класса GameScene на SKScene. Хотя теперь он работает с другими классами SKScene, я до сих пор не понимаю, что это такое.

Для чего этот метод? я должен держать его?


person lisovaccaro    schedule 24.08.2014    source источник


Ответы (2)


Я мало использовал Xcode 6, но вот мое понимание (кто-то может исправить меня или пояснить):

Вот как ваше приложение использует данные макета и т. д. для GameScene (или любого SKScene). Если вы щелкните файл GameScene.sks на панели Project Navigator, вы получите визуальный редактор для вашей GameScene.

Если вы хотите, чтобы эти данные макета использовались, вы должны использовать этот метод. Вы можете визуально компоновать GameScene в редакторе сцен без необходимости кодировать местоположения, настройки и т. д.

person prototypical    schedule 24.08.2014
comment
Я вижу, все в игре в основном динамическое, поэтому я не мог понять, для чего нужны файлы .sks, и просто удалил их. Буду иметь в виду, если решу их использовать. - person lisovaccaro; 24.08.2014
comment
Если вы внимательно изучите элементы, которые вы можете перетаскивать на сцену, и изменить настройки для данного элемента, я думаю, вы найдете это полезным. Такие вещи, как эмиттеры, пружины, гравитационные поля, поля турбулентности и т. д. Это кажется довольно многообещающим, хотя кажется, что некоторые вещи не работают в бета-версии, которая у меня была. (или я что-то пропустил в настройках) - person prototypical; 24.08.2014
comment
Если бы вы разрабатывали игру Angry Birds, вы могли бы начать с создания различных уровней в коде. Вам нужно будет установить фон, выбрать и расположить птиц, которых нужно запустить, построить конструкцию(и), защищающую свиней, и расположить свиней в соответствующих местах. Представьте, что вы делаете все это в коде для 100 уровней. Apple предоставила средства для графической настройки уровней с помощью шаблона SpriteKit и редактора SpriteKit. Вместе они позволяют отделить содержимое сцены (GameScene.sks) от игровой логики (GameScene.m). - person 0x141E; 24.08.2014
comment
Я понимаю. Я собирался попробовать реализовать тайловую карту. Практично ли создавать игровую карту с помощью файлов sks?? - person lisovaccaro; 25.08.2014

Следуя комментарию 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 {
...
person ubersnack    schedule 27.11.2014