簡體   English   中英

子類化使用SpriteKit .sks場景文件創建的SKNode

[英]Subclassing SKNodes created with SpriteKit .sks scene file

(這適用於XCode 6和iOS 8 beta 4)

喜歡新的SceneKit編輯器。 我已成功將場景從.sks文件加載到自定義SKScene類中。 但是,其中的對象被實例化為默認類(SKNode,SKSpriteNode等),我不確定如何將它們綁定為實例化為自定義子類。

目前,我通過創建自定義類並鏈接到Sprite節點作為屬性來解決此問題,並且可以正常工作

目前,您應該在添加到SpriteKit游戲模板中的方法中按名稱進行操作。 他們在WWDC 2014的SpriteKit最佳實踐視頻中涵蓋了此主題。由於視頻中包含很多內容,因此很容易錯過。

這是方法。

+ (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上的類別,其中包括從mainBundle中的.sks文件加載時使用NSKeyedUnarchiver替代Class的方法。 在iOS中,他們將其添加到GameViewController.m文件中,在OS X中,將其添加到AppDelegate.m文件中。

在這里或您自己的SKNode子類中,您可以實現此功能。 這是他在下面的帖子中所做的。 這是由Apple提供的,並在WWDC視頻中進行了介紹。 我想明年會更好。 在此期間,請求SKNode的錯誤獲得類似於IBDesignable for Scene Editor的錯誤。 :)

我寫了一個小助手代表來解決這個問題: https : //github.com/ice3-software/node-archive-delegate 它使用NSKeyedUnarchiverDelegate來按名稱NSKeyedUnarchiverDelegate進行子類化。

我做了一個小技巧,如何使用SceneKit編輯器,我將嘗試使用它,但是我不確定如何降低性能。 我想使用場景編輯器制作復雜的SKNodes結構並將其加載到當前場景中。 它還可以幫助子類化節點。

我在場景編輯器中配置節點,將父節點設置為名為“ base”的空節點,並成為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
    }
}

就像我說的那樣,我不確定生產率,但是我認為,如果不經常使用它,不會造成太大的傷害。 希望這對某人有幫助。

是的,Apple應該使我們所有人都更容易做到這一點,但是就目前而言,這是我需要的最可行的解決方案:

避免子類化

當然,這可能根本不可能,但是就我而言,我想到的子類包含控制我在SKS文件中布局的圖形的邏輯……聽起來與ViewController非常接近,不是嗎?

我創建了一個OverlayController類,並使用以下代碼對其進行了初始化:

self.childNodeWithName(Outlet.OverlayNode)!

因此,現在,overlay節點只是一個啞節點,而controller是具有所有優點的完整子類。

但是還有更多

只是把它扔進去就可以使交易變甜:

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

這是新控制器類文件中的一個私有擴展,因此我們可以輕松地訪問啞SKNode的子SKNode

痛點

令人痛苦的一點是觸摸處理。 將SKNode子類化以進行自定義觸摸處理是很自然的,並且合成方法幾乎無法在此方面做任何事情。 我目前正在從現場轉發觸摸,但是如果有更好的方法,我會發布更新。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM