Nicholas
Nicholas

Reputation: 13

Going to the previous scene SpriteKit

I'm making a game. On the main menu I have a button for "Start Game" "High Scores" "Options" "Store".

I have various scenes for the different levels. Each of those scenes has a "pause button" which takes you to the "Options" scene. The Options scene has a "BACK" button.

How do I get that "BACK" button to return to what have scene called it?

Right now the "BACK" button only has the ability to return to the menu ie SceneSkip in my code, regardless of what scene called it:

func back(){
        let sceneSkip = SceneSkip(fileNamed: "SceneSkip")
        sceneSkip?.scaleMode = .aspectFill
        self.view?.presentScene(sceneSkip!, transition: SKTransition.fade(withDuration: 0.5))
}

Upvotes: 0

Views: 585

Answers (2)

Ron Myschuk
Ron Myschuk

Reputation: 6061

I think that your are going about "levels" in a difficult way.

What I suggest you do is...

Have a scene for your menu which transitions to your GameScene.

In your GameScene you load all generic objects that are common to the game regardless of the level (such as gameHud, score labels, pause buttons, options buttons etc.)

you then load your level scene into GameScene based on a parameter (levelID).

this way none of your generic objects have to be created in multiple scenes greatly reducing the chance of redundancy errors.

Completely optional portion

I don't like to switch scenes in the middle of a game for pausing or options. it creates to many opportunities for something to go wrong (failing to load data, failing to save locations, score, animations etc.).

I create my pause and option dialogs as SKSpriteNodes and pause the game and display the dialog over top of the GameScene. That way when I am done with the dialog I can just remove it, and unpause the game and everything goes back to how it was without having to load the scene all over.

enter image description here

Upvotes: 1

Dennis
Dennis

Reputation: 615

So I've been working on a game in my spare time and I have solved pretty much exactly what you're doing. Here are a couple things I learned in the process.

1) When you present a scene, your scene's didMove(to: view) method is going to be called. Usually you do your initialization in that method so if you are just pausing, and you present the scene again, you're likely going to mess up the game state.

2) Because of number 1, you can't really present a new scene each time the user wants to pause.

So... the solution I've been using, which is the result of a number of google searches, experimenting and etc, is to actually use a separate view for all my popup/pause type scenes. I set it up like this in my GameViewController viewWillLayoutSubviews where skView is the main view:

let psize = view.bounds
popup = SKView.init(frame: psize)
skView.addSubview(popup!)
popup?.allowsTransparency=true
popup?.isHidden=true

Then, later when any scene anywhere in the game wants to add a popup, I added the following functions:

func showPopupScene(_ scene : SKScene) {

    (self.view as? SKView)?.scene?.isPaused = true
    popup?.isHidden=false
    popup?.presentScene(scene)

}

func closePopup() {
    popup?.isHidden=true
    if let v=view as? SKView {
        (v.scene as? PopupNotify)?.onPopupClosed()
        v.scene?.isPaused=false
    }
}

Now, any scene can create a scene, and show it as a popup with showPopupScene. The popup scene then needs to call closePopup and the game returns to the scene where it left off.

Other items:

I wanted my game scenes to behave correctly with pausing popups as well as when they are paused from coming out of background etc... so I override isPaused:

override var isPaused : Bool {
    get {
        guard let v = self.view?.window?.rootViewController as? GameViewController else {
            return super.isPaused
        }
        guard let p = v.popup else { return super.isPaused }
        return super.isPaused || !p.isHidden
    }
    set(newPaused) {
        super.isPaused = newPaused
        physicsWorld.speed = newPaused ? 0 : 1.0
    }
}

Also, the PopupNotify protocol for my scenes helped where I wanted scenes to be aware that the popup was closed in case they needed to make any changes according to whatever the popup was showing.

Hope I'm not forgetting anything, but the combination of these additions has provided pretty easy popup/pause management.

Upvotes: 1

Related Questions