Sunday, November 23, 2014

Singletons in ds.oop and Phaser State Management

State management is one of the things that separates a demo from a complete game. Phaser has a great state manager that helps to get states up and running quickly. While writing a game state manager is a good academic exercise for any game developer but since phaser already has one I'll just use it instead of writing my own.

So lets just get right into the code. We will be using the ds.oop framework to create a static class to encapsulate the phaser game and state management system. This class allows us to setup the state switching in one place which makes it easier to read and makes it easy to load states from a json file or later if we want.

// Singleton Class
ds.make.static.class({
    type: 'Game.State',
    constructor: function () {
        this.width = 800;
        this.height = 600;
        this.game = new Phaser.Game(this.width, this.height, Phaser.WEBGL, 'cartest');
        this.states = [];

        this.add(Game.Boot);
        this.add(Game.Loader, false);
        this.add(Game.World);
        this.start();
    },
    add: function (stateClass, clearWorld, clearCache) {
        this.game.state.add(stateClass.prototype.type, stateClass);
        this.states.push({
            state: stateClass.prototype.type,
            clearWorld: clearWorld,
            clearCache: clearCache
        });
    },
    start: function () {
        this.stateIndex = -1;
        this.next();
    },
    next: function () {
        var p = this.states[++this.stateIndex];
        this.game.state.start(p.state, p.clearWorld, p.clearCache);
    }
});

So this is the entry point for our phaser game. The constructor creates the phaser game object and adds all the game states. The add method will cache the parameters for the game.state.start method until we are ready to switch the state. The state order is completely linear in this example but it would be trivial create a branching structure that switches states conditionally if needed.

Here is the first state class. I created this jut as an example to show how the state switching works now. As you can see there is no need to keep track of which state is next. The order is already set in the Game.State class. All we are doing is calling the next() method to signal the state change.

ds.make.class({
    type: 'Game.Boot',
    create: function () {
        Game.State.next();
    }
});

The first task for our state manager is to display some graphic like a loading bar while the user waits for the game assets to load. The loading screen is a standard way to manage loading assets in a game. Here i'm just updating some text with the percentage loaded. Later we will load some loading screen assets and display an animated loading screen with a progress bar but for now this should give you the general idea.

ds.make.class({
    type: 'Game.Loader',
    preload: function() {
        var style = { font: "12px Lucida Console", fill: "#ffff44", align: "left" };
        this.text = this.game.add.text(5, 5, 'Loading...', style);
        this.text.fixedToCamera = true;
        // Load all the assets here
    },
    loadUpdate: function () {
        this.text.setText('Loading: ' + this.game.load.progress + '%');
    },
    create: function () {
        Game.State.next();
    }
});

Part 2 of this tutorial coming soon...

1 comment:

  1. Woow this is very neat, please do write a part2 and 3 :)
    I want to know how do u use YUI Compressor with this.

    Thanks

    ReplyDelete