Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon


29. May 2014

 

 

One thing every single game has in common is a game loop.  That said, it’s not always under your control!  Today we are going to look at how the game loop is implemented in the Phaser HTML5 game engine.

 

Pretty much every single video game ever created follows the same basic program flow:

 

Program Starts

Check Input

Update World

Draw scene

Program Exits

 

Of course this is a massive simplification ignoring things like updating physics simulations, multiple threads, streaming of assets, etc… but the basic flow is there in every game.  The three indented process, Input, Update and Draw are performed over and over in a loop, thus “game loop”.  In Phaser there is no exception, but the way it’s handled is a bit different.

 

If you’ve done any JavaScript game development before you’ve no doubt encountered requestAnimationFrame or if using an older browser setTimeout JavaScript functions.  Both perform basically the same task, they call a function once an interval, such as every 30th of a second if your game is set to run at 30fps.  This is the very heart of most JavaScript games and Phaser is no exception.  You the end developer don’t have to care about such low level aspacts though as this functionality is taken care of in the class Phaser.RequestAnimationFrame and is automatically created by Phaser.Game.  If you want to see the actual game loop driving your game though, I suppose this code snippet from RequestAnimationFrame.js is it:

 

    updateRAF: function () {

        this.game.update(Date.now());

        this._timeOutID = window.requestAnimationFrame(this._onLoop);

    }

 

As you can see, its basically just calling Game’s update() over and over.  Now if we take a look at the source code for update in Game it all becomes clear:

 

update: function (time) {

    this.time.update(time);

    if (!this._paused && !this.pendingStep) {
        if (this.stepping) {
            this.pendingStep = true;
        }

        this.debug.preUpdate();
        this.physics.preUpdate();
        this.state.preUpdate();
        this.plugins.preUpdate();
        this.stage.preUpdate();

        this.state.update();
        this.stage.update();
        this.tweens.update();
        this.sound.update();
        this.input.update();
        this.physics.update();
        this.particles.update();
        this.plugins.update();

        this.stage.postUpdate();
        this.plugins.postUpdate();
    }
    else {
        this.state.pauseUpdate();
        // this.input.update();
        this.debug.preUpdate();
    }

    if (this.renderType != Phaser.HEADLESS) {
        this.renderer.render(this.stage);
        this.plugins.render();
        this.state.render();
        this.plugins.postRender();
    }

}

 

So there is your traditional game loop, just nicely tucked away.  So then, where then does your code fit in all of this?  Remember back in the Hello World post when we created a Game instance we past in a “State” object implementing create and passed in the function this.create to be called, like so:

this.game = new Phaser.Game(800, 600, Phaser.AUTO, 'content', { create: this.create });

 

Well, that’s how we do it.  A State object has a number of functions that will be called, in this case we provide an implementation for create, now lets look at a slightly more complicated example:

 

class SimpleGame {

    constructor() {
        this.game = new Phaser.Game(800, 600, Phaser.CANVAS, 'content', {
            create: this.create, update: this.update,
        render: this.render});
    }

    game: Phaser.Game;
    textValue: Phaser.Text;
    updateCount: number;

    create() {
        var style = { font: "65px Arial", fill: "#ff0000", align: "center" };
        this.textValue = this.game.add.text(0, 0, "0", style);
        this.updateCount = 0;
    }

    update() {
        this.textValue.text = (this.updateCount++).toString();
    }

    render() {
        this.game.debug.text("This is drawn in render()", 0, 80);
    }
}

window.onload = () => {
    var game = new SimpleGame();
};

 

Here is the code running:

 

 

In this example the State object we are passing in to the Phaser.Game constructor implements create, update and render.  Create will be called once, predictably enough on creation.  Here we create a red text object like we did in the Hello World example.  This time however we keep a reference to it.  We also add a counter variable updateCount.  Each frame update() will be called, we simply increment the counter value and assign this to out text object.  Finally in render we draw our text using game.debug.text().  Phaser provides a number of convenient debug methods for dumping information on screen, either as text or graphically.  These functions however are *NOT* optimized and should not be used in production!

 

So as you can see, update works pretty much like you would expect, but instead of your game controlling the loop you implement methods in a State object that will be called by the Phaser engine.

 

Let’s look at a slightly more complex example that will probably make State objects make a bit more sense.  This is a two screen game, first there is a title sreen shown that when clicked then moves to the game state, which is the same as the above demo.  Let’s jump in with code:

 

module GameFromScratch {
    export class TitleScreenState extends Phaser.State {
        game: Phaser.Game;
        constructor() {
            super();
        }
        titleScreenImage: Phaser.Sprite;

        preload() {
            this.load.image("title", "TitleScreen.png");
        }
        create() {
            this.titleScreenImage = this.add.sprite(0, 0, "title");
            this.input.onTap.addOnce(this.titleClicked,this); // <-- that um, this is extremely important
        }
        titleClicked (){
            this.game.state.start("GameRunningState");
        }
    }

    export class GameRunningState extends Phaser.State {
        constructor() {
            super();
        }
        textValue: Phaser.Text;
        updateCount: number;

        create() {
            var style = { font: "65px Arial", fill: "#ff0000", align: "center" };
            this.textValue = this.game.add.text(0, 0, "0", style);
            this.updateCount = 0;
        }

        update() {
            this.textValue.text = (this.updateCount++).toString();
        }

        render() {
            this.game.debug.text("This is drawn in render()", 0, 80);
        }
    }

    export class SimpleGame {
        game: Phaser.Game;

        constructor() {
            this.game = new Phaser.Game(800, 600, Phaser.WEBGL, 'content');

            this.game.state.add("GameRunningState", GameRunningState, false);
            this.game.state.add("TitleScreenState", TitleScreenState, false);
            this.game.state.start("TitleScreenState", true, true);
        }

    }
}

window.onload = () => {
    var game = new GameFromScratch.SimpleGame();
};

 

And when you run it you see ( click to proceed ):

 

One thing to be aware of right away is this example should probably be split across 3 files not in a single one.  I kept them together to make following along easier.

 

Here, instead of creating a state object inline we declare two of them.  Here we are using the TypeScript ability extend to create Phaser.State derived objects as inheritance really isn’t part of JavaScript. Let’s take a quick look at what this code does, starting with SimpleGame.

 

Here instead of providing a State object to the Phaser.Game constructor inline ( in { } form ) we register 2 different states using game.state.add().  The first value is the string value we will access this state using, the second is the state itself while the final value is if you want to start the state while adding it.  Finally after adding each state we start one calling game.stat.start and pass in the key value of the state.  Yes, we could have simply added true when we added the TitleScreenState, but I think doing it long form is clearer.

 

Once our TitleScreenState starts, in preload it loads an image, then in create it adds the image as a sprite.  Finally it adds a tap handler that will be called when the screen is tapped.  Image loading, sprites and input will all be covered later.  One very important thing to understand here though is the this parameter passed in to onTap.addOnce.  The second value is the context that titleClicked will be called in.  In other words, the value of “this” within titleClicked is determined by the value you pass here.  This is one of the warts of JavaScript IMHO and I wished TypeScript fixed it, although it appears it hasn’t.  The importance here is, if you don’t pass the context into the Signal (onTap) then the called function (titleClicked) wont have access to itself!  You will then get an error that this.game is undefined.  Finally when titleClicked is called we launch the GameRunningState like we did earlier.  GameRunningState is basically just the functionality from our earlier example split out into Phaser.State form.

 

As you can see, Phaser.State objects allow you to logically split up your game functionality.  Of course you could just implement a single inline state like we did earlier and ignore them from this point on.

 

Programming , , , , ,

blog comments powered by Disqus

Month List

Popular Comments

Tizen $10,000 For Top 100 Apps Contest Announced
Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon


14. December 2016

 

Tizen is an open source embedded OS based on the Linux kernel designed to be used in a variety of devices, the most relevant to game developers are Smart TVs and mobile phones.  It came to life out of a home grown OS project at Samsung called Bada.  To date the majority of devices that run Tizen are from Samsung including the Z1 and Z3 smart phones, Gear 2 smart watch and the JU6500 4K smart TV, although other manufacturers are part of the committee.  Basically you can think of Tizen as Samsung’s hedge against Android should something go wrong with that platform.

So… why does this matter to you as game developers?  Well Tizen just announced a contest with some pretty simple rules and $9million in prizes.  Basically over a 9 month period, the top 100 apps in the Tizen app store will get $10,000.  So if you manage to have a top 100 app for the entire duration of the contest, you will make a cool $90,000 on top of any other revenue you make from app sales.  While the Tizen app store may not be the biggest in the world, a $10,000 monthly incentive is sure to draw developer interest.

 

Details of the contest:

HOW TO
PARTICIPATE

  • 1.Develop a Tizen application or game using TIZEN SDK & Tools (http://developer.tizen.org) The target devices should be Samsung Z1, Samsung Z2, Samsung Z3 and further smart phones launch in the 2017.
  • 2.You need to join the Tizen Store seller office
    (http://seller.tizenstore.com) first and follow the instructions on the website to register your applications.
  • 3.Visit the incentive program website, which will be opened on the early of January 2017, and register your app with its basic information.

TIMELINE

Participation Registration Period
Early of Jan, 2017 – Oct 31, 2017 (GMT)
Program Duration
Feb 1, 2017 at 00:00 - Oct 31, 2017 at 23:59(GMT)

INCENTIVE
REWARDS

Prize
$10,000 for top 100 apps every month(The reward can be provided at once per a app)
Judging Criteria
Every month, the 100 eligible applications that have
been downloaded the most times on Tizen Store.(Detailed rules will be released in January 2017)

 

Tizen support is available in several game engines including Unity, Cocos2d-x, GameSalad, OpenFL and GameMaker.

GameDev News

blog comments powered by Disqus

Month List

Popular Comments