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子类化以进行自定义的触摸处理是很自然的,组合方法在这方面几乎没有做任何事情。 我现在正在转发现场的接触,但如果有更好的方法,会发布更新。