The codeleap for this section may be accessed here. In this section, we will discuss organizing a game into Scenes. Following this explanation, we will implement a bit of Scene Control.
Subsections
01 A Word on Scene Control
02 Scene Methods
03 Scene Flow Control
So far we’ve been working mostly in the root scene. This is fine for prototyping, but for a polished game experience we want to organize our game into different scenes. This can include a title scene, some kind of scene explaining controls, an option scene, and most importantly a game scene. Alternatively, we can also divide the game scene into multiple scenes for different levels.
enchant.js organizes scenes in a stack format. By default, the root scene is the only thing on the stack. Thankfully, enchant.js provides a few methods that help with scene flow: replace, push, and pop.
The replace method takes in a scene R_SCENE as a parameter, removes the current scene from the stack, and then sets R_SCENE as the current scene.
The push method takes in a scene P_SCENE as a parameter and pushes it on top of the stack, making P_SCENE the current scene. The previously current scene still exists on the stack below P_SCENE.
The pop method removes the current scene from the stack, and sets the current scene to the scene below it.
Now that we’ve discussed the scene stack methods, let's try implementing it. In our example, we’re going to move everything from the root scene and organize it into different scenes.
Let’s implement Scene Flow in our example code. (Once again, you can access it from here.)
var TitleScene = Class.create(Scene, {
initialize: function(){
console.log("title created!");
Scene.apply(this);
titleBG = new Sprite(stageWidth, stageHeight);
titleBG.image = game.assets['scene-title.png'];
this.addChild(titleBG);
var btn = new Button(0);
this.addChild(btn);
}
});
TitleScene
. When TitleScene
is initialized, a background image sprite called titleBG
is instantiated and added to TitleScene
. A Button sprite called btn
is also instantiated and added to TitleScene
.ontouchend
function, you'll see an if/else
branch. Depending on this.choice
, the button calls one of the scene method: replace. In this case, this.choice === 0
. Therefore, when btn
is clicked, it instantiates a new GameScene
and replaces the current scene with it.
var GameScene = Class.create(Scene, {
initialize: function(){
console.log("game created!");
Scene.apply(this);
gameBG = new Sprite(stageWidth, stageHeight);
gameBG.image = game.assets['scene-gamebg.png'];
this.addChild(gameBG);
var player = new Player();
this.addChild(player);
}
});
GameScene
. When GameScene
is initialized, a background image sprite called gameBG
is instantiated and added to GameScene
. A Player sprite called player
is also instantiated and added to GameBG
.onenterframe
function, you'll see a call to popScene. Once player
's age reaches 60, it pops GameScene
off of the stack, moving the scene called GameOverScene
to the top.
var GameOverScene = Class.create(Scene, {
initialize: function(){
console.log("game over created!");
Scene.apply(this);
gameoverBG = new Sprite(stageWidth, stageHeight);
gameoverBG.image = game.assets['scene-gameover.png'];
this.addChild(gameoverBG);
var btn = new Button(1);
this.addChild(btn);
}
});
GameOverScene
. When TitleScene
is initialized, a background image sprite called gameoverBG
is instantiated and added to GameOverScene
. A Button sprite called btn
is also instantiated and added to GameOverScene
.ontouchend
function. This time, this.choice === 1
. Therefore, when btn
is clicked, it instantiates a new TitleScene
and pushes the new TitleScene
onto the stack.
gameOver = new GameOverScene();
game.pushScene(gameOver);
title = new TitleScene();
game.pushScene(title);
gameOver
and pushes it onto the stack, then does the same for a new TitleScene called title
. Setting it up this way makes sure that when the game is started, title
is the first thing the user sees, and gameOver
is always just above the rootScene.