3

私が作成しているゲームでは、簡単にロードできる多くのカスタム レベルを作成できるようにしたいと考えています。各レベルには、.sks インターフェイス ファイルと独自の SKScene サブクラス .swift ファイルが必要です。 Xコード

現在、これは機能しています:

extension SKScene {
    class func unarchiveFromFile(file : NSString, theClass : AnyClass!) -> SKScene? {
        if let path = NSBundle.mainBundle().pathForResource(file, ofType: "sks") {
            var sceneData = NSData.dataWithContentsOfFile(path, options: .DataReadingMappedIfSafe, error: nil)
            var archiver = NSKeyedUnarchiver(forReadingWithData: sceneData)

            archiver.setClass(theClass, forClassName: "SKScene")
            let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as SKScene
            archiver.finishDecoding()
            return scene
        } else {
            return nil
        }
    }
}

このようなシーンを作成する場所:

if let scene = SKScene.unarchiveFromFile("Level1", theClass: Level1.classForKeyedUnarchiver())

しかし、これは大規模なコレクションでは機能しません。これは、たとえばコレクションのフォルダー内の各レベルを反復処理できないためです。私はこのようなものが必要です

if let scene = SKScene.unarchiveFromFile("Level1", className:"Level1")

この回答を使用して、このような文字列からクラスを取得しようとしましたが、シーンは Level1 オブジェクトではなく単なる SKScene であるかのように読み込まれました。

let classFromString: AnyClass! = NSObject.swiftClassFromString("Level1")
    if let scene = SKScene.unarchiveFromFile("Level1", theClass: classFromString)

今のところ、これで作業しますが、これが最善のアプローチだとは思いません。

let levels = [
    ("Level1", Level1.classForKeyedUnarchiver()),
    ("Level2", Level2.classForKeyedUnarchiver())]

let level1 = levels[0]
let (fileName : String, theClass: AnyClass!) = classes[0]
if let scene = SKScene.unarchiveFromFile(fileName, theClass: theClass)

簡単にロードできる SKScene サブクラスの大規模なコレクションを、それぞれ独自のインターフェイス ファイルで作成できるようにしたいだけです。

4

1 に答える 1

4

これは、次を使用して実行できますNSClassFromString

スウィフト 2 の場合:

extension SKScene {
    static func sceneWithClassNamed(className: String, fileNamed fileName: String) -> SKScene? {
        guard let SceneClass = NSClassFromString("Your_App_Name.\(className)") as? SKScene.Type,
              let scene = SceneClass.init(fileNamed: fileName) else { 
            return nil 
        }

        return scene
    }
}

またはスウィフト1:

extension SKScene {
    static func sceneWithClassNamed(className: String, fileNamed fileName: String) -> SKScene? {
        if let SceneClass = NSClassFromString("Your_App_Name.\(className)") as? SKScene.Type,
           let scene = SceneClass(fileNamed: fileName) {
            return scene
        }

        return nil
    }
}

使用法:

if let scene = SKScene.sceneWithClassNamed("MyScene", fileNamed: "MyScene") {
    view.presentScene(scene)
}

これが正しく機能するには、SKSceneサブクラスinit(coder aDecoder: NSCoder)で を実装する必要があることに注意してください。たとえば、次のようになります。

required init?(coder aDecoder: NSCoder) {
    // ...
    super.init(coder: aDecoder)
}
于 2014-09-24T19:00:01.680 に答える