如何将 SpriteKit 存档与 SKSpriteNode 子类一起使用



如何使用 SpriteNode 所在的 spritekit 存档文件,并将该 SpriteNode 实例化为子类(使用 Swift?(

我可以使用 scene.childNodeWithName("mysprite"( 找到节点,但我不知道如何将其变成我的 SKSpriteNode 子类的实例。

Xcode 6 的 SpriteKit 编辑器中无法为节点设置自定义类。(不过,这将是一个很好的功能请求,可以向Apple提交。

但是,您在 Xcode 中生成的sks文件只是NSKeyedArchiver存档,您可以使用NSKeyedUnarchiver选项来控制对象在加载时的实例化方式。因此,有一个(有限的(选项可以在加载时更改类 — 当您在 Xcode 6 中创建新的 SpriteKit Game 项目时,您可以在模板代码中看到这一点。

请参阅GameViewController.m中的SKNode扩展(或 ObjC 版本中的类别(:它使用 NSKeyedUnarchiver 方法setClass(_:, forClassName:)将存档中的SKScene实例视为模板项目的 GameScene 类的实例。您可以扩展此模式以从 Xcode 创建的存档创建其他自定义场景类。

但是,您会注意到,setClass(_:forClassName:)基于类名工作,因此如果您的存档包含同一类的多个对象,并且您希望将其中一个对象解码为与其他对象不同的类,则它的用处有限。在这种情况下,您可以考虑使用其他解压缩器技巧,例如,替换 unarchiver(_:didDecodeObject:) 委托方法中的对象。

您可以使用

此委托 https://github.com/ice3-software/node-archive-delegate或者,为了快速实施,SMT 如下所示:

class func unarchiveNodeFromFile(file:String)-> SKNode? {
    if let path = NSBundle.mainBundle().pathForResource(file, ofType: "sks") {
        var fileData = NSData.dataWithContentsOfFile(path, options: NSDataReadingOptions.DataReadingMappedIfSafe, error: nil)
        var archiver = NSKeyedUnarchiver(forReadingWithData: fileData)
        archiver.setClass(self.classForKeyedUnarchiver(), forClassName: "SKNode")
        let node = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as SKNode
        archiver.finishDecoding()
        return node
    } else {
        return nil
    }
}

最新更新