【发布时间】:2023-04-07 03:39:01
【问题描述】:
如何使用 SpriteNode 所在的 spritekit 存档文件,并让 SpriteNode 实例化“进入”子类(使用 Swift?)
我可以使用 scene.childNodeWithName("mysprite") 找到节点,但我不知道如何将它变成我的 SKSpriteNode 子类的实例。
【问题讨论】:
标签: swift sprite-kit
如何使用 SpriteNode 所在的 spritekit 存档文件,并让 SpriteNode 实例化“进入”子类(使用 Swift?)
我可以使用 scene.childNodeWithName("mysprite") 找到节点,但我不知道如何将它变成我的 SKSpriteNode 子类的实例。
【问题讨论】:
标签: swift sprite-kit
没有办法在 Xcode 6 的 SpriteKit 编辑器中为节点设置自定义类。(不过,如果要向 Apple 提交 feature request,那就太好了。)
但是,您在 Xcode 中生成的 sks 文件只是 NSKeyedArchiver 存档,您可以使用 NSKeyedUnarchiver 选项来控制对象在加载时如何实例化。因此,在加载时更改类有一个(有限的)选项——当您在 Xcode 6 中创建新的 SpriteKit 游戏项目时,您可以在模板代码中看到这一点。
查看GameViewController.m 中的SKNode 扩展(或ObjC 版本中的类别):它使用NSKeyedUnarchiver 方法setClass(_:, forClassName:) 将存档中的SKScene 实例视为模板项目@ 的实例代替 987654332@ 类。您可以扩展此模式以从 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
}
}
【讨论】: