inheritance使用SpriteKit .sks场景文件创build的SKNodes
(这是XCode 6和iOS 8 beta 4)
喜欢新的SceneKit编辑器。 我成功地从.sks文件加载到一个自定义SKScene类的场景。 然而,它里面的对象被实例化为默认类(SKNode,SKSpriteNode等),我不知道如何绑定它们来实例化为自定义子类。
目前,我正在通过创build自定义类和链接到精灵节点作为一个属性来解决这个问题,并且工作正常
我写了一个小帮手委托来处理这个问题: https : //github.com/ice3-software/node-archive-delegate 。 它使用NSKeyedUnarchiverDelegate
通过名称子类化你的精灵。
目前你应该在添加到SpriteKit游戏模板的方法中按名称来完成。 他们在WWDC 2014的SpriteKit最佳实践video中介绍了此主题。由于video有很多内容,因此很容易错过。
这是方法。
+ (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
从mainBundle中的.sks文件加载时replace类的方法。 在iOS中,他们将其添加到GameViewController.m
文件中,并在OS X中将它添加到AppDelegate.m
文件中。
在这里或在你个人的SKNode子类中,你可以实现这个。 这是他在post里所做的。 这是由苹果提供,并在WWDCvideo中报道。 我想明年它会得到更好的处理。 与此同时,一个请求SKNodes的bug会得到类似于场景编辑器的IBDesignable。 🙂
我做了一个小技巧如何使用SceneKit编辑器,我会尝试使用它,但我不确定这会如何降低性能。 我想使用场景编辑器来制作复杂的SKNodes结构并将它们加载到当前场景中。 它也可以帮助子类化节点。
我在场景编辑器中configuration节点,将父节点设置为名为“base”的空节点,并创buildSKNode的子类。 然后我做了一个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 } }
正如我所说,我不确定生产力,但我认为如果不经常使用它,也不会太多太多。 希望这有助于某人。
是的,苹果应该让我们所有人都更容易,但是暂时来说,这是我最需要的解决scheme:
避免子类化
当然,这可能根本不可能,但在我的情况下,我想到的子类包含控制在SKS文件中放置的graphics的逻辑…听起来很接近ViewController,不是吗?
我创build了一个OverlayController
类,并用下面的代码初始化它:
self.childNodeWithName(Outlet.OverlayNode)!
所以,现在,覆盖节点只是一个愚蠢的节点,控制器是完整的子类,具有所有的好东西。
但还有更多
只要投入这个来促进交易:
private extension SKNode { var progressBar: SKNode { return self.childNodeWithName("ProgressBar")! } }
这是新的控制器类文件中的一个私有扩展,所以我们可以无痛地访问哑SKNode
的子SKNode
。
痛点
一个公认的痛苦点是触摸处理。 将SKNode子类化以进行自定义的触摸处理是很自然的,组合方法在这方面几乎没有做任何事情。 我现在正在转发现场的接触,但如果有更好的方法,会发布更新。