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


23. May 2014

 

 

I believe there is an old law or charter that requires all programming adventures to start off with a Hello World application, and who am I to break the law ( or charter ) ?

 

Of course before you get started, you have to choose your tools.  One of the cool things about working in HTML5 is you can simply pick your favorite text editor ( such as Sublime Text or Notepad++ ) and just start typing.  TypeScript adds a small layer of complexity over top but not too much.  I’ll cover TypeScript in a second, in the meanwhile back to the tools.  Personally I like working in an IDE like environment, integrating as much of the development cycle ( build-compile-run-debug, although not all are relevant to HTML5 ) in a single location.  For TypeScript development there are two clear leaders to chose from, both of which I have access to licenses for.  Visual Studio and WebStorm.  You can use the Express versions of Visual Studio to do TypeScript development if you don’t have a full license, while Webstorm is available with a 30 day license ( and is well worth the 50$! ).

 

Personally I chose Visual Studio 2013 for a couple reasons.  First, I’ve been doing lots of Java development lately, so I miss the familiar comforts of Visual Studio, which in my opinion is still the best IDE on the market.  Second, Microsoft developed TypeScript, so you have to imagine the tooling support is pretty good.  And it is.  Of course you’ve got solid code completion, error checking and syntax colouring:

image

 

Perhaps more importantly, debugging support works as well.  You can set breakpoints, inspect values and step line by line:

image

 

However, there is a problem I encountered here in Visual Studio 2013.  It simply wouldn’t hit any breakpoints I set in code.  Granted, this is a bit of a big problem, no?  Anyways my solution was pretty simple… add the generated JS files to the project and you are good to go:

 

image

 

There is probably a better solution, but this worked for me.  Oh, speaking of Visual Studio 2013 problems, I encountered another one.  When you try to create a new TypeScript project, you may be prompted to install TypeScript for Visual Studio 2013.  However, when you click the link for it, it brings you to the website for TypeScript for Visual Studio 2012!  If you want to do TypeScript development in Visual Studio 2013 you need to download and install Visual Studio 2013 Update 2.  Advanced warning, it’s 3.6GB.  Of course, if you’ve been using Visual Studio recently, or just downloaded it, you probably already have Update 2 installed so it wont impact you.  Me, I was out and used my mobile connection to download the update… ouch!

 

Otherwise for getting started with Phaser in Visual Studio using TypeScript this tutorial is a great place to start.  A few things have changed ( like the above mentioned Get TypeScript link process no longer working ) and a few of the generated names are different ( default.htm is now index.html ), but otherwise it will get you up and running in a few minutes.  Basically you just download or clone Phaser from Git.  Truth is though you only need to add a few files to your project all available in this folder.  The files of importance are phaser.js and phaser.d.ts.  The first file is Phaser itself ( the .min version is optimized for size for when you deploy, but use the full slower to load version for development ) and the .d.ts are the TypeScript definitions.

 

 

Why TypeScript

 

You may be asking what exactly TypeScript is?

It’s a Microsoft created language designed to make JavaScript development easier.  One thing to be aware of upfront, TypeScript IS JavaScript, in that 100% of JavaScript is valid TypeScript.  This makes TypeScript a superset of JavaScript.  You could take any .js file, rename it .ts and it will run just fine.  At the end of the day, all TypeScript is compiled down to ordinary JavaScript, remarkably readable JavaScript to boot.

 

The “Super” part of superset is what makes TypeScript so useful.  Basically it adds a number of constructs on top of the language that make dealing with some of JavaScript’s worst warts easier.  More than anything, TypeScript allows you to deal with increasingly complex applications, something JavaScript really doesn’t make easy.  That’s all nice and good to say but you may be asking How?  Good question!

 

First of all TypeScript adds a Type system on top of JavaScript… thus the name.  JavaScript has very mutable types… if you pass a string where it expects a number, it happily converts as best it can, even if that isn’t what you want.  With TypeScript, if you define a type for a variable then use it wrong it will catch it at compile time.  This alone should cut down on hoards of logic errors.  Of course for those that want JavaScript style ducktyping “any” exists.

 

Second, TypeScript adds classes, something that is coming in the future for JavaScript.  This allows data hiding ( marking members as private ) as well as built in constructor support.  Data hiding is something JavaScript desperately needs, allowing multiple programmers to write code that doesn’t stomp all over each other.  TypeScript also adds the interface, which is a class without implementation, or somewhat easier to grok as a “contract”.  TypeScript also enables generics.

 

Third and somewhat related to the second, it also adds Modules, something modern day JavaScript hacks in using closures.  If you have used C++, Java or C#, think namespaces.  There is also functionality in there to make the JavaScript experience more consistent such as always prefering === for comparisions ( 1 == “1” isnt true in Typescript, in fact it’s an error ), consistent this handling, etc.

 

It’s Microsoft, shouldn’t I be afraid?

When it comes to programming languages this is a perfectly legit concern when it comes to Microsoft.  Many of us remember the “embrace and extend” approach of J#, which was a Microsoft supplied Java implementation that only worked on Windows machines.  JScript.NET and Managed C++ can certainly be looked at as lesser evils created by Microsoft.

 

In the case of TypeScript though, this isn’t really valid for a couple reasons.

  • it’s open source.  Real open source too not some fake opensource lite ( Its Apache 2.0 by the way ).  So if they try to make it MS only people can literally tell them to fork off.
  • there is nothing Microsoft specific in there.
  • at the end of the day, it compiles down to JavaScript.

 

TypeScript is hardly unique, is it?

Nope, there are other languages that work in a very similar manner and work to solve the same problems.  The closest two are CoffeeScript and Google’s Dart.  That said there are tons of other languages that compile into JavaScript such as GWT ( Java to JavaScript ), Haxe, Kotlin ( Kotlin –> JVM –> JavaScript ) and probably a few dozen’s more.  What makes TypeScript most appealing to me is it’s simularity to normal JavaScript ( unlike CoffeeScript ) and it’s not Google ( unlike Dart and GWT )… what can I say, I’ve been burned too many times from Google’s horrific developer support.  Unlike Microsoft, Dart does very much have vendor tie in ( Chome/ChromeOS native Dart support ), something to be very aware of!

 

Ok… set up, tooling and language bits behind us, let’s take a look at a simple Phaser app!

 

First you have your host index.html.  This is the webpage you load in your browser to get things started:

 

<!DOCTYPE html>

<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>Hello Phaser</title>
    <link rel="stylesheet" href="app.css" type="text/css" />
    <script src="phaser.js"></script>
    <script src="app.js"></script>
</head>
<body>
    <div id="content"></div>
</body>
</html>

 

Most important lines here are the two <script> tags, bringing in first the Phaser libraries then your generated js code.  ( app.ts will automatically be converted to app.js by Visual Studio when you run if no errors occur ).

 

Now let’s take a look at App.ts:

 

class SimpleGame {

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

    game: Phaser.Game;

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

}

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

 

And that’s it.  Run it and your selected browser should automatically open and you should see:

image

 

Humble beginnings certainly, but beginnings all the same!

This is about the simplest Phaser application you can make.  The key line is creating game, a new instance of the Phaser.Game class.  The values we are passing in are the width, height, renderer, parent and a collection of functions that can will be called during the programs lifecycle.  The width and height are self explanatory.  The renderer tells Phaser how to render your game, using Canvas, WebGL or Headless ( for server side apps that don’t render ).  The value Phaser.AUTO let’s Phaser decide.  ‘content’ is the name of the HTML element to render to, you may notice back in the HTML file our DIV name is content, this is what connects Phaser to your HTML. The final value { create: this.create } is a name value pair saying for the “create” function use this.create.   There are a number of States that Phaser can be in, create, preload, render, update.  In this case we are simply defining the create state, so when Phaser enters a create state, our game’s create function will be called.

 

In the create method we simply create a text object and add it to our game using this.game.add.text().  The style value is in traditional CSS styling format.  The Text value is obviously the text to display.  Finally we wire up window.onload() to create an instance of our game starting the whole process off.  If you aren’t used to JavaScript programming window is a top level global object provided by the browser, onload is the method called predictably enough when your webpage loads.

 

Essentially the work flow goes:

  • user opens page in web browser
  • Phaser.js script is run and Phaser is loaded.
  • Your app ( app.js ) code is loaded
  • Your app registers a create method and creates a game instance then registers an onload handler.
  • webpage finishes loading, your pages onload is called creating an instance of your game.
  • Phaser enters a create state and your create() function is called.

 

Normally your application would continue to cycle through the various states ( update/render mostly ) and this is where your game would “run”.  We will look at this in more detail soon.

 

All told I have to say my initial impressions of Phaser are incredibly good.  There are hundreds of examples, the documentation is ample and well written.  Obviously it’s too early to comment on performance, design or other technical aspects yet.

 

Programming


GFS On YouTube

See More Tutorials on DevGa.me!

Month List