Подтвердить что ты не робот

Подкласс SKNodes, созданный с помощью файла сценария SpriteKit.sks

(это для XCode 6 и iOS 8 beta 4)

Возлюбите новый редактор SceneKit. Я успешно загружаю сцену из файла .sks в собственный класс SKScene. Тем не менее, объекты внутри него создаются как классы по умолчанию (SKNode, SKSpriteNode и т.д.), И я не уверен, как их привязывать к экземпляру вместо пользовательских подклассов.

В настоящее время я обойдусь тем, что создавая пользовательские классы и привязывая к вершинам спрайтов как свойство, и это работает нормально

4b9b3361

Ответ 1

Я написал маленького помощника делегата, чтобы справиться с этим: https://github.com/ice3-software/node-archive-delegate. Он использует NSKeyedUnarchiverDelegate для подкласса ваших спрайтов по имени.

Ответ 2

В настоящее время вы должны делать это по имени в методе, добавленном в шаблоны игр SpriteKit. Они освещают эту тему в видеоролике SpriteKit Best Practices на WWDC 2014. Легко пропустить, потому что в нем много чего.

Вот этот метод.

+ (instancetype)unarchiveFromFile:(NSString *)file {
    /* Retrieve scene file path from the application bundle */
    NSString *nodePath = [[NSBundle mainBundle] pathForResource:file ofType:@"sks"];
    /* Unarchive the file to an SKScene object */
    NSData *data = [NSData dataWithContentsOfFile:nodePath
                                          options:NSDataReadingMappedIfSafe
                                            error:nil];
    NSKeyedUnarchiver *arch = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    [arch setClass:self forClassName:@"SKScene"];
    SKScene *scene = [arch decodeObjectForKey:NSKeyedArchiveRootObjectKey];
    [arch finishDecoding];

    return scene;
}

Это категория на SKScene, которая включает в себя метод использования NSKeyedUnarchiver для замены класса при загрузке из файла .sks в mainBundle. В iOS они добавляются в файл GameViewController.m, а в OS X они добавляются в файл AppDelegate.m.

Здесь или в ваших индивидуальных подклассах SKNode вы можете реализовать это. Это то, что он сделал ниже в своем посте. Это было предоставлено Apple и охвачено видео WWDC. Думаю, в следующем году все будет лучше. Тем временем файл с ошибкой, запрашивающий SKNodes, получает что-то вроде IBDesignable для Scene Editor.:)

Ответ 3

Я сделал небольшой трюк, как использовать редактор SceneKit, и я попытаюсь его использовать, но я не уверен, как это может снизить производительность. Я хочу использовать редактор сцен, чтобы создавать сложные структуры SKNodes и загружать их в текущую сцену. Он также может помочь с узлами подкласса.

Я настраиваю свой node в редакторе сцены, устанавливаю родительский node как пустой node, называемый "базой", и создавал подкласс SKNode. Затем я сделал метод init и назову его, когда мне нужно в моей сцене:

// subclass code
class MyOwnSKNodeSubclass: SKNode {

let nodeLayer = SKNode()

   init(fromNode: SKNode){
       super.init()

       nodeLayer.addChild(fromNode.childNodeWithName("base").copy() as SKNode)
       addChild(nodeLayer)
   }
}



// scene code
if let myNode = SKNode.unarchiveNodeFromFile("MyScene")
{
   // you can use your subclass here
   let node = MyOwnSKNodeSubclass(fromNode: myNode)

   addChild(node)
}

Я также использовал собственное расширение SKNode, но не большую разницу, но:

class func unarchiveNodeFromFile(file:String) -> SKNode?{

    if let path = NSBundle.mainBundle().pathForResource(file, ofType: "sks") {
        var nodeData = NSData.dataWithContentsOfFile(path, options: .DataReadingMappedIfSafe, error: nil)
        var archiver = NSKeyedUnarchiver(forReadingWithData: nodeData)

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

Как я уже сказал, я не уверен в производительности, но полагаю, что это не повредит слишком много, если не использовать это очень часто. Надеюсь, это поможет кому-то.

Ответ 4

Да, Apple должна сделать это проще для всех нас, но на данный момент это наиболее жизнеспособное решение для моих нужд:

Избегать подклассов

Конечно, это возможно не совсем возможно, но в моем случае подкласс, который я имел в виду, содержит логику для управления графикой, которую я выложил в файле SKS... Звучит ужасно близко к ViewController, не так ли

Я создал класс OverlayController, и я инициализирую его с помощью

self.childNodeWithName(Outlet.OverlayNode)!

Итак, теперь наложение node является просто немым node, а контроллер - полноценным подклассом, который имеет все полезные свойства.

Но есть больше

Просто бросьте это, чтобы подсластить сделку:

private extension SKNode {
    var progressBar: SKNode {
        return self.childNodeWithName("ProgressBar")!
    }
}

Это частное расширение внутри нового файла класса контроллера, поэтому мы можем безболезненно обращаться к дочерям немого SKNode.

Точка боли

По общему признанию, болезненным моментом является сенсорная обработка. Естественно подклассифицировать SKNode для пользовательской обработки касания, и композиционный подход практически ничего не делает на этом фронте. На данный момент я перенаправляю штрихи со сцены, но буду отправлять обновления, если есть лучший способ.