I’m working on a puzzle game in Phaser3 and I want to create a blue sky with animated clouds as the background.
So I thought I create a separate scene, put all the animation code there and re-use that scene in all other scenes, so in the MainMenu, LevelSelect, GameScene etc.
The reason I want to do it as a a separate scene, is so I don’t have to add the same functions and animation code to each scene. And also so that the animation doesn’t reset when switching between the MainMenu scene to the GameScene, so it should continue seemlessly when the player changes scenes and starts the game.
So my question is:
how can I use a singleton scene as a background scene for all other scenes?
I know it’s possible in Phaser3 to layer scenes, for example show scenes within a scene. But I couldn’t find a code example of using it as one singleton background scene.
See the example code below, you can copy&paste into the Phaser3 sandbox to run it. It’s a simple example and I’ll add better graphics later, but first I need the code to work properly.
class MyBackground extends Phaser.Scene
{
constructor ()
{
super('MyBackground');
}
preload()
{
// blue to white
var clr_g1 = 0x0000ff; //blue
var clr_g2 = 0xffffff; //white
// create background graphic: a large rectangle
let bg_sky = this.add.graphics();
//bg_sky.fillGradientStyle(clr_g1, clr_g1, clr_g2, clr_g2); // gradient doesn't work with generateTexture?
bg_sky.fillStyle(0x8080ff);
bg_sky.fillRect(0, 0, 800, 600);
// draw random clouds
for (var i=0; i < 12; i++)
{
// random position
var size = Phaser.Math.Between(50, 100);
var xpos = Phaser.Math.Between(size, 800-size);
var ypos = Phaser.Math.Between(0, 600);
bg_sky.fillStyle(0xE0E0E0, 1.0);
bg_sky.fillEllipse(xpos, ypos, 2.0*size, 1.0*size);
bg_sky.fillStyle(0xFFFFFF, 1.0);
bg_sky.fillEllipse(xpos, ypos-(0.1*size), 1.6*size, 0.8*size);
}
// turn graphics into texture
bg_sky.generateTexture('background', 800, 600);
bg_sky.setVisible(false);
}
create ()
{
this._bg_image = this.add.tileSprite(400, 300, 800, 600, 'background');
this._bg_off = 0;
}
update (time, delta)
{
this._bg_off = this._bg_off + 0.2;
this._bg_image.setTilePosition(this._bg_off, 0);
}
}
class MenuScene extends Phaser.Scene
{
constructor ()
{
super('MenuScene');
}
create ()
{
this.add.text(20, 20, "THIS IS THE MENU-SCENE");
// Phaser3 has no buttons, create a make-shift button
var game_btn = this.add.graphics();
game_btn.fillStyle(0xff0000);
game_btn.fillRect(100, 300, 300, 50)
game_btn.setInteractive(new Phaser.Geom.Rectangle(100, 300, 300, 50), Phaser.Geom.Rectangle.Contains);
game_btn.on('pointerdown', function() { this.scene.start('GameScene') } , this);
this.add.text(100, 300, "click to switch to game-scene");
}
}
class GameScene extends Phaser.Scene
{
constructor ()
{
super('GameScene');
}
create ()
{
this.add.text(400, 20, "THIS IS THE GAME-SCENE");
// Phaser3 has no buttons, create a make-shift button
var game_btn = this.add.graphics();
game_btn.fillStyle(0xff00ff);
game_btn.fillRect(150, 100, 300, 50)
game_btn.setInteractive(new Phaser.Geom.Rectangle(150, 100, 300, 50), Phaser.Geom.Rectangle.Contains);
game_btn.on('pointerdown', function() { this.scene.start('MenuScene') } , this);
this.add.text(150, 100, "click to switch to menu-scene");
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#000000',
parent: 'phaser-example',
scene: [ MyBackground, MenuScene, GameScene ]
};
const game = new Phaser.Game(config);