Loading an SKNode from a .sks scene file in Swift

2019-04-30 00:52发布

I want to use multiple .sks files to store some complex SKNode hierarchies such as game menus. I have a background with moving objects I'd like to keep throughout the game, so presenting different SKScenes doesn't achieve what I want. I am restricted to one scene, but I'd still like to separate out my code from artwork as much as possible, and trying to squeeze everything into one .sks file gets crowded quick!

So I'd like to have multiple .sks files, each one storing a different menu: titleMenu, getReadyMenu, pauseMenu, gameOverMenu, with all the elements of each menu a descendent of an empty SKNode.

I have managed to load the files, cache the SKNode in a local variable, and display it on screen, but when I click on the buttons for the menu, the touchesBegan function is never called, when I click just outside the buttons on the menu it is normal responder chain functionality. Very perplexing.

I am sure my solution is so convoluted that is would be simpler to just ask if someone could post an example of grabbing out just an SKNode (and children) from a .sks file, without presenting a new scene.

So, can someone please post an example of this in Swift?

1条回答
forever°为你锁心
2楼-- · 2019-04-30 01:29

When creating a new project, select the Game template. GameViewController.swift will have the following extension implementation defined at the top of the file:

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

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

I haven't done this in Swift, but am reasonably experienced with this stuff using Objective-C and it works nicely.

查看更多
登录 后发表回答