Friday, February 26, 2016

"Loading" Screens in Phaser Games

I noticed an annoying thing when playing my Phaser platformer on Amphibian.com - it was taking a really long time to start the levels. The problem was mainly that I was re-loading the game assets every time a level was started, and that I wasn't pre-loading them way back before the title screen.

Loading...

I wanted to fix this issue and add a "Loading" screen at the beginning before the main stage select menu was available. The way to do this is to add a few more states to the game.

First, I added a boot state. All this state will do is load the title background image and an image that says "Loading." This happens in the preload function, and should go fairly quickly. In the create function for this state, which will be called as soon as preload completes, it will immediately start the next state - the real preloader. Check out the following code from the game (remember, the full source code is available on GitHub):

var boot = {
  
    preload: function() {
        this.game.load.image("title", "assets/images/title.png");
        this.game.load.image("title-loading", "assets/images/title-loading.png");
    },
    
    create: function() {
        this.state.start("preloader");
    }
        
};

The second state I added was called preloader. This will serve as the game's real preloader. I moved the asset pack loading from my other two existing states (the menu and the playable level) to the preload function of this state. But before I start loading assets, I display the two assets I loaded in the boot state's preload. I can use those assets here because they were loaded before this function - even though this is a preload function it's not the first one. Basically, you can use assets in preload as long as they've already been loaded by a previous state's preload. This will show the player the nice title screen and let them know that the game is loading. After all the assets are loaded, the create function is called for this state, which changes to the stageSelect state.

var preloader = {
  
    preload: function() {
        
        this.add.image(0, 0, "title");
        this.loadingText = this.add.image(450, 200, "title-loading");
        
        this.load.pack("main", "assets/pack.json");

    },
    
    create: function() {
        this.state.start("stageSelect");
    }
        
};

Now when I set up my game, I add all 4 states and then start the boot state.

var game = new Phaser.Game(width, height, Phaser.CANVAS, "gameArea");

game.state.add("boot", boot);
game.state.add("preloader", preloader);
game.state.add("stageSelect", stageSelectState);
game.state.add("level", theStage);

game.state.start("boot");

It still takes a while to load all the assets, but at least now you know what's going on. And once you make it to the menu, all the levels will start immediately for you. Much better. The process of loading assets still takes a while because the background music files are so large. I'll probably fix that by reducing their quality a little. Don't worry, you won't notice.

You might notice something wrong with today's comic, however...

Amphibian.com comic for 26 February 2016