2

Alright, so I have sprite kit game in Swift and I've created my game in the GameScene.swift file that apple sets up for you, and that all works great. Now I want to create another game scene within this same project.

When the game is over, right now the game moves to a new UIViewController (named GameOverBufferViewController) that I've set up in the storyboard. But I want it to move to a completely new game scene.

So I looked at how GameViewController loads in GameScene.swift (because the game scenes need a view controller as well as the SKScene code) and copied it into the view controller file for my UIViewController that the game moves to when it's game over.

I changed the references to GameScene to match my new game scene swift file (GameOverScene1) and the unarchiveFromFile func to avoid an error:

import UIKit
import SpriteKit

extension SKNode {
    class func unarchiveFromFile2(file : NSString) -> SKNode? {
        if let path = NSBundle.mainBundle().pathForResource(file as String, 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! GameOverScene1
            archiver.finishDecoding()
            return scene
        } else {
            return nil
        }
    }
}


class GameOverBufferViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        if let scene = GameOverScene1.unarchiveFromFile2("GameOverScene1") as? GameOverScene1 {
            // Configure the view.

            let skView = self.view as! SKView

            skView.showsFPS = true
            skView.showsNodeCount = true
            skView.showsPhysics = false

            /* Sprite Kit applies additional optimizations to improve rendering performance */
            skView.ignoresSiblingOrder = true

            /* Set the scale mode to scale to fit the window */
            scene.scaleMode = .AspectFill

            skView.presentScene(scene)

        }


    }

Then here I set up my GameOverScene1.swift file:

import SpriteKit

class GameOverScene1: SKScene {

    override func didMoveToView(view: SKView) {

        //Do stuff in scene
        println("it works!")
    }
}

And the game runs without any errors or crashing but GameOverScene1 isn't run; it just goes to GameOverBufferViewController. Nothing is printed to the console either.

What am I doing wrong?

EDIT********

This is what my GameOverBufferViewController file looks like now and I get a SIGABRT error saying could not cast a UIView as an SKView:

import UIKit
import SpriteKit

class GameOverBufferViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
            // Configure the view.

            back()


    }
    func back() {
        view.subviews.map({ $0.removeFromSuperview() })

        let theView = view as! SKView //error on this line
        let theMainMenu = GameOverScene( size: view.frame.size )
        theMainMenu.scaleMode = SKSceneScaleMode.ResizeFill

        theView.presentScene( theMainMenu )

    } 
blue
  • 7,175
  • 16
  • 81
  • 179

3 Answers3

0

I just use this:

func back() {
    let theView = view as! SKView
    let theMainMenu = MainMenu( size: view.frame.size )
    theMainMenu.scaleMode = SKSceneScaleMode.ResizeFill

    theView.presentScene( theMainMenu )
}

MainMenu is a subclass of SKScene.

EDIT:

Make sure you are declaring your view as a UIView when your main ViewController's viewDidLoad() function runs. Like this:

override func viewDidLoad() {
    super.viewDidLoad()

    let theView = view as! SKView
    let theWelcome = Welcome( size: view.bounds.size )
    theWelcome.scaleMode = SKSceneScaleMode.ResizeFill

    theView.presentScene( theWelcome )
}
jmcmahon443
  • 202
  • 2
  • 14
0

Try This:

    let SceneMove = SceneName(size: self.scene!.size)
    SceneMove.scaleMode = SKSceneScaleMode.AspectFill
    self.scene!.view!.presentScene(SceneMove)

SceneName is of course the name of your scene.

Credit From skyguy and the link he posted: How to transition scenes in Swift

Community
  • 1
  • 1
neptunes
  • 72
  • 5
0

I think the problem comes from your "unarchiveFromFile" function of the extension SKNode.

Try to change this line:

let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as! GameOverScene1 

to this :

let scene = archiver.decodeObjectForKey(NSKeyedArchiveRootObjectKey) as! SKScene

Also note that you do not need to have many "unarchiveFromFile" functions for each new scene (each new level), just define one after your imports in the GameViewController class.

Edess Elder
  • 1,461
  • 13
  • 9