Advanced Phaser and TypeScript Projects

This tutorial is a follow-up to the TypeScript with Phaser beginners guide. I will assume you have worked through that tutorial already and have a working set-up in which you can compile Phaser projects. From this base we will expand on the simple approach taken in the beginners guide and show how to structure a more advanced project that benefits from the power of TypeScript.

Create a new Project

In the first tutorial everything was hanging off a single app.ts file with one bundled class. This time around we’re going to break it up into more individual classes. In Visual Studio create a new empty TypeScript project, then add the phaser TypeScript definition and JS library files to it as outlined in Step 2 in the first tutorial.

Download this asset pack and unzip it into the project folder. We’ll reference these files in our code.

Create a new TypeScript file called Game.ts and add this code to it:

Here we have created a new Module called Castlevania under which all of our game classes will live. Obviously you’d change this to whatever your game is actually called, unless you’re genuinely working on a Castlevania game, in which case I’m eternally jealous :)

The Game class is extending Phaser.Game. As a result we need to call super in the constructor and pass in our game settings. Once done we add 4 States to the game: Boot, Preloader, MainMenu and Level1, and then start the Boot state. You don’t have to add ALL of the States at this point, but there is no harm in doing so.

When adding this code in Visual Studio you may notice that Boot, Preload, MainMenu, and Level1 are underlined in red. This is because they don’t yet exist within the Project.

part1

Let’s Boot

Create a new TypeScript file called Boot.ts and paste this code in:

Our Boot class is where we define global settings for the game. It’s also were we preload the graphics that will be used by the actual Preloader, in this case a simple loading bar image.

The create function is called after the image has loaded. In the code above you can see that we’re setting the maximum number of pointers to 1 and disabling the ‘pause’ checks. This isn’t a require of Phaser, it’s just a good example of the sort of things that go into a common Boot script. This is also where you would define how the game handles scaling. For example if this was aimed at mobile and needed to run at iPad resolution (1024×672) then we would usually add the following code into the ‘mobile settings’ part of the class:

The code above isn’t needed for this tutorial however.

When all of this has finished Phaser swaps to the Preloader state.

Creating our Preloader, extending a Phaser.State

Create a new TypeScript file called Preloader.ts and paste the following code in:

This class is extending Phaser.State. This means you’ve got instant access to all the properties of the State object. Phaser uses a set of specially named functions to perform tasks, one of which is preload. Inside here we can queue calls to Phasers asset loader. As you can see in the code above we’re loading a variety of assets: some images, a sprite sheet and an mp3.

We also create a sprite called preloadBar and link it to the asset loader. It will be automatically cropped as the files load in, making the effect of a preloader bar increasing over time as each file completes:

part2

When the load is finished the create function is called, which is when we fade the preload bar away. On completion of that tween we start the main menu. If you run the game locally you probably won’t even see the preload bar fill-up as the assets will load from the local filesystem too fast to be noticed, but once out in the wild this won’t be an issue and it’ll be important to offer a decent looking preloader screen.

Once everything has finished we start the MainMenu.

The Main Menu

For this tutorial our menu is a picture and a game logo with a couple of simple tweens. Obviously you’ll want to enhance this for your own games, but it serves our purpose here. Create a new file called MainMenu.ts and paste this code in:

I won’t explain all of it because it should start becoming quite familiar by now. A couple of Sprites, tweens to make them appear. Then the game waits for an input event before fading out and starting the Level1 class. When you run it the menu will look like this:

part3

Not too bad :)

Extending Phaser.Sprite

Create a new TypeScript file called Level1.ts and add this code to it:

We aren’t going to cover creating a fully working game here, but I do want to use this file to highlight extending Phaser Sprites. In the code above you’ll see a local variable called player that is an instance of Castlevania.Player. Create a new TypeScript file called Player.ts and paste this code in:

Here our Player object is extending Phaser.Sprite. As a result we have direct access to all Sprite properties from within it, which is why we can set the velocity directly on the body for example. Upon instantiation a few visual properties are set and an animation walk cycle added. Finally the sprite is added to the game world via game.add.existing(this).

Once the sprite is added to the game world its update function will be called every frame. So to take advantage of this we set the players velocity if the left or right arrow keys are held down. As you’d expect this allows you to make the player walk left or right and animate accordingly. The end result looks like this:

part4

We didn’t have to check for input within the Player class. We could have added an update function to the Level1 class instead and then told the Player to move as a result of that, but it highlighted an important choice: it’s up to you how your code is structured. So long as you adhere to a few basic rules and remember the names of the special Phaser functions, you can achieve pretty much any set-up you require or are familiar with.

Compiling to a single JS file

I’m sure you are keen to try out the project, but first let’s make a couple of small but vital tweaks so we can build it. Enter the Project properties by selecting Properties from the Project menu. Then click the TypeScript Build category on the left and change the settings to match this:

part5

The important things to do are:

  • Make sure the ECMAScript version is set to ECMAScript 5.
  • Set the Module system to None
  • Check ‘Combine JavaScript output into file’ and enter ‘game.js’ as the filename

Save the changes to the Project Properties. What we’ve done is make sure that the whole project will be compiled into a single JavaScript file called game.js. This won’t include Phaser but it will include all of your game code. The last couple of changes we need to make are to the default.htm and app.ts files:

Here we’ve included the single output file game.js. And app.ts is reduced to simply this:

With all of these files in place you should be able to compile and build the project. And with it you should have a pretty good base from which to build out a complete future game. You can also download all of the Visual Studio project files. We’ve more Phaser tutorials coming, so keep an eye out for them and subscribe to our Phaser newsletter for details.

Castlevania is © Copyright Konami 1988. All rights reserved and is used for illustration purposes only.

Posted on December 11th 2013 at 11:19 pm by .
View more posts in Phaser. Follow responses via the RSS 2.0 feed.


31 Responses

Leave a comment
  • Shimon
    December 12th 2013 at 9:29 am

    My eyes are watering. I just can’t get over the beauty of that code. Keep up the good work. At this rate Phaser.js will cure cancer by the end of the decade.

  • December 31st 2013 at 5:23 pm

    Keep up the good work! TypeScript is awesome. Thanks for making some tutorials for it

  • January 6th 2014 at 11:33 pm

    Wow thanks, that helped a lot. I just started a little game and had to figure out myself what works and what not. I got a lot of improvements from this code :)

    Looking forward to contribute my part to Phase. I love it.

  • Hermann
    January 19th 2014 at 4:03 pm

    Great tutorial! It helped me a lot getting started with my own project.
    Thank you!

  • February 1st 2014 at 10:57 pm

    I was able to setup and run the first example without issue. This second one is giving me an error though – and doesn’t execute, of course. In app.ts I have the following:

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

    But it tells me that the module “Castlevania” is not defined. Imagine I’m missing something really obvious here?

  • February 1st 2014 at 11:59 pm

    Are the relevant JS files being included in the html at all?

  • February 2nd 2014 at 12:15 am

    Strange. It appears the only JS being included is app.js and phaser.js! Have you seen this before? Using VS Web Express 2013.

  • February 2nd 2014 at 12:22 am

    That will be fine as long as you’ve set VS to compile it all to a single js file on build. I’ve not used Web Express before, does the Project Properties panel look any different at all?

  • February 2nd 2014 at 12:31 am

    Ah, that was it! Needed the name of the single file and the reference in the HTML to match. Been a long day :/

    Yes, the properties are basically identical.

  • Robin
    February 2nd 2014 at 7:30 pm

    If you’re trying to get this working in CoffeeScript, it seems you need to pass in a new instance of your extended state classes, as opposed to just the class itself. Like so:

    @game.state.add(‘Boot’, new Game.StateBoot, false)

    If you don’t, you get cryptic errors and spend the your Sunday morning with great sadness. :P

  • February 20th 2014 at 12:45 am

    How are resources unloaded? When I switch to a new state, does the old state’s assets get unloaded automagically or I need to call manually some function? Can I keep a state in memory so I can pop back to it. I’ve seen engines with a state stack approach, would that work with Phaser or would I need to reload all resources when going back and forth between states? Just wondering how I can build my screens with phaser at this point. Excellent work btw! You gave my the push I needed to work in typescript :)

  • February 20th 2014 at 1:12 am

    When you swap state you have the option to clear either just the world (which is the same as clearing the display list), or clearing the cache. This will nuke anything loaded by that point. The default is not to do this, so assets persist from state to state. It’s up to you to decide which to kill or not really :)

  • February 20th 2014 at 1:36 am

    Just to be sure: my clearing the world, you mean removing all instanced objects like sprites, graphics, text, etc? And by clearing the cache, you mean clearing sounds, textures, etc?

    If so, what happens if I clear the cache but not the world? :)

  • February 20th 2014 at 1:47 am

    You can’t :) If you set clearCache to true it will only run if you have clearWorld true as well.

  • February 20th 2014 at 1:51 am

    Just to be sure: by clearing the world, you mean removing all instanced objects like sprites, graphics, text, etc? And by clearing the cache, you mean clearing sounds, textures, etc?

  • February 21st 2014 at 2:09 am

    Thank you very much for this tutorial boss :-D

  • Morgan
    March 5th 2014 at 2:09 am

    This is exactly what i was looking for. However, i find that after following these instructions, my instance of VS 2013 web produces the following output:

    Referenced file ‘~/Scripts/_references.js’ not found.
    Referenced file ‘game.js’ not found.

    After this, my intellisense stops working. Very frustrating. Does anyone have any advice on how i might be able to resolve this output? Thank you.

  • Morgan
    March 5th 2014 at 2:16 am

    In Response to my last comment, i fixed my issue by disabling the TypeScript build option ‘Combine JavaScript output into file’, Cleaning and re-building my solution. Sorry guy’s, i spend my days in eclipse/Drupal land, and its been awhile since i have worked with VS. However if anyone has any further advice to add, i would love to hear it. Thank you for the great tutorial, and please, keep ‘em coming!

  • Juan Camilo
    April 20th 2014 at 3:52 am

    Thanks! This framework is really Amazing, only one thing, it threw an error saying that body was undefined, I had to add the line “game.physics.enable(this, Phaser.Physics.ARCADE)” in player constructor to properly run the example. Could you update that please?

  • Craig
    April 20th 2014 at 8:55 am

    It looks like the physics body was not set up on the Sprite? I get this:

    Uncaught TypeError: Cannot read property ‘velocity’ of null in update() on class Player from this line of code:

    this.body.velocity.x = 0;

  • Billy
    May 5th 2014 at 6:14 pm

    here is my Level1 codes.
    module Castlevania {

    export class Level1 extends Phaser.State {

    background: Phaser.Sprite;
    music: Phaser.Sound;
    player: Castlevania.Player;

    create() {

    this.background = this.add.sprite(0, 0, ‘level1′);
    this.add.tween(this.background);
    this.music = this.add.audio(‘music’, 1, false);
    this.music.play();

    this.player = new Player(this.game, 130, 284);

    }

    }

    }

  • Billy
    May 5th 2014 at 7:08 pm

    in above post, i cannot get the level sprite to load, niether the player nor the backgrou nd will load after manin menu screen. how can I fix it?

  • Billy
    May 6th 2014 at 5:41 pm

    update, I have decided to abandon typescript and go with plain JS. much less problems this way imo. Did the dev stop work on typescript too?. I really like typescript in theory, but i dont think its ready for this type of use yet, at least not without a team of devs to work on it regularly.

  • PriorBlue
    May 7th 2014 at 6:35 pm

    @Craig:

    i have added this line to the constructor:
    game.physics.enable(this, Phaser.Physics.ARCADE);

    Now it works for me.

  • Noam
    May 21st 2014 at 12:05 am

    Im using visual studio 2012 and for some reason i dont have that TypeScript Build section in the properties, what am i supposed to do/do you know what this would happen?
    Also, is there anyway to run the program while coding in a debug sort of way?

  • Reisor
    May 21st 2014 at 12:26 am

    You forget to add two things that are critical if you want to run the game, because without them you will get a black screen when starting ‘Level1′ and an error that ‘Player’ didn’t have the ‘velocity’ property

    In Boot.ts you need to add this line before calling the Preloader:

    this.game.physics.startSystem(Phaser.Physics.ARCADE);

    And in the Player.ts you have to add:

    this.game.physics.arcade.enableBody(this);

  • Dan
    May 21st 2014 at 5:07 pm

    Hi – I’m new using typescript and Phaser. Im OSX using Webstorm, I would really be grateful if you could outline how to combine the JS into a single file if your not using VS. Or an alternative to getting the demo working in Webstorm. Appreciate your effort supporting the community!

  • Aykut
    May 24th 2014 at 9:15 pm

    @Reisor
    Thank you. That helped a lot.

  • Gaz
    September 1st 2014 at 6:26 pm

    Hey, great tutorial here. I’m having a little trouble with this line though:

    this.input.onDown.addOnce(this.fadeOut, this);

    The problem is with this.fadeOut, it doesn’t know what that is. I get the red underline and the message when I hover over is “the property ‘fadeOut’ does not exist on value of type ‘MainMenu’.”

    Can anyone help?

  • Gaz
    September 1st 2014 at 6:28 pm

    Nevermind, I’m an idiot it seems. Needed to add the function, duh.

Make yourself heard