divillysausages.com

Using Phaser with Visual Studio Code

| Permalink

With all my main writing tasks completed, I've been looking to expand my horizon a bit, and one project I've had my eye on for a while is Phaser, a desktop and mobile HTML5 game framework.

HTML5 games have been on my bucket list for ages, but I've held off until it was more mature, there was better tooling support, and smarter people than me figured out all the stingers. Phaser is created by Photon Storm, who've been working in HTML5 games for a long time, and along with others, have poured countless hours into creating the most starred JavaScript game framework on GitHub.

Seems good enough for me.

Enter TypeScript and Visual Studio Code

While you could write pure JS, much in the same way as you could eat your dinner by having someone throw it at your face from across the room, a more sensible approach is to using something like TypeScript, a Microsoft-developed superset of JavaScript that compiles down to pure JS. The syntax is extremely familar if you're coming from something like ActionScript, so while it has some flaws, it's a great choice.

Added to that, Microsoft have also released Visual Studio Code, a free, cross-platform IDE, specifically geared towards ASP.NET and NodeJS. Visual Studio Code also supports TypeScript, and did I mention that it's free?

It's still under heavy development, but if there's one thing Microsoft do well, it's developer tools.

Setting up Phaser, TypeScript, and Visual Studio Code

I didn't see much info on getting all these to play nice, so this is a quick step-by-step guide on getting a development environment up and running.

As of writing this, I'm running Visual Studio Code 0.3.0, Phaser 2.3.0, TypeScript 1.5.0-beta (the necessary version for VSC), and NodeJS 0.12.4. Later versions might require different steps. I'll also say, that I'm not an expert in at least 3 of these, so there might be easier ways to do things. *Might*.

Installing everything

First up, actually installing everything you'll need for this, i.e. getting Visual Studio Code, NodeJS, TypeScript, and Phaser from the internet and onto your computer.

Once everything is installed, you're ready to rock.

Creating your TypeScript project

For Visual Studio Code, a TypeScript project is a folder where a tsconfig.json file, their equivalent of a project file, can be found.

Click File > Open Folder. You can create a new one if you want.

Open a folder to create a TypeScript project

For the purposes of this tutorial, and polluting my folders, I've used the name MyProj.

Next up, right-click, select New File and name it tsconfig.json.

Create a tsconfig.json file to it's recognised as a project

The great thing about Visual Studio Code is that it recognises this type of file immediately, so you get auto completion even though it's a simple JSON file. Fill it out with the following code:

{
	"compilerOptions": {
		"target": "ES5",
		"module": "commonjs",
		"sourceMap": false
	}
}

For now, the details aren't too important, but if you want more info on what goes into a tsconfig.json file, you can get it here. The only thing I would say, is set sourceMap to true if you want to generate sourcemaps for your compiled JS, which lets you debug it using the original TypeScript code.

The tsconfig.json file layout

Adding Phaser to the project

To add Phaser to your project, you'll need 4 files minimum, which you'll find wherever you downloaded Phaser to:

The first one is so that you can actually play your game, while the last 3 are TypeScript definition files, for P2 physics, Phaser, and PixiJS respectively, and are necessary if you want to have code completion in your project (the answer to this is "yes").

How you set up your project is up to you, but I put the phaser.js file in the bin/js/ folder, and the TypeScript definition files in the tsDefinitions/ folder. The bin/ folder is essentially what you're going to upload to your server, so all game files and assets need to be here.

Adding the phaser files to the project

Creating your simple game

I followed this basic "How to use Phaser with TypeScript" tutorial to get the code for this, but all we're going to do is create a simple state that displays our logo on the screen.

The image I'm using, ds_logo.png, is my basic game logo, but you can use whatever you want. I've placed it in the bin/assets/ folder.

The code for your SimpleGame, saved as Game.ts in the src/ folder is:

class SimpleGame
{
	game:Phaser.Game;
	
	constructor()
	{
		// create our phaser game
		// 800 - width
		// 600 - height
		// Phaser.AUTO - determine the renderer automatically (canvas, webgl)
		// 'content' - the name of the container to add our game to
		// { preload:this.preload, create:this.create} - functions to call for our states
		this.game = new Phaser.Game( 800, 600, Phaser.AUTO, 'content', { preload:this.preload, create:this.create} );
	}
	
	preload()
	{
		// add our logo image to the assets class under the
		// key 'logo'. We're also setting the background colour
		// so it's the same as the background colour in the image
		this.game.load.image( 'logo', "assets/ds_logo.png" );
		this.game.stage.backgroundColor = 0xB20059;
	}
	
	create()
	{
		// add the 'logo' sprite to the game, position it in the
		// center of the screen, and set the anchor to the center of
		// the image so it's centered properly. There's a lot of
		// centering in that last sentence
		var logo = this.game.add.sprite( this.game.world.centerX, this.game.world.centerY, 'logo' );
		logo.anchor.setTo( 0.5, 0.5 );
	}
}

// when the page has finished loading, create our game
window.onload = () => {
	var game = new SimpleGame();
}
Creating the SimpleGame class

If VSC is giving you any gyp about Phaser being an unrecognised variable, or you don't have code completion when you type, add:

/// <reference path="../tsDefinitions/phaser.d.ts" />

to the head of the file. This is the TypeScript equivalent of the import statement. Note that we're importing the TypeScript definition file (or source map, if you will), not the phaser.js code file itself.

We also need to create a simple HTML file that will actually display our game. The following is index.html, saved in the bin/ folder:

<!DOCTYPE html>
<html>
	<head>
		<title>Simple game</title>
		<script src="js/phaser.js"></script>
		<script src="js/game.js"></script>
	</head>
	<body>
		<h1>Simple game</h1>
		<div id="content"></div>
	</body>
</html>
Creating the index.html page

The only thing we're doing is adding the js/phaser.js file, and the js/game.js file, and creating a div element named content (the same name we passed to the new Phaser.Game(...) call).

js/game.js doesn't actually exist yet, through, because we haven't compiled our SimpleGame TypeScript class down to pure JS. Let's do that now.

Building our project

By default, TypeScript will take one ts file and produce one js file. As it would get old *really* quickly to add all the JS files of any decent size project to the page (not to mention organising them in order of dependancies, and all the extra round-trips to the server), we can optionally compile everything down to one file (hint: game.js).

The default shortcut key for building in Visual Studio Code is Ctrl+Shift+B. The first time you press this, you'll see a message on the top of the screen along the lines of "No task runner configured", with a button, "Configure task". That's a button you'll want to press.

VSC will now spit out a tasks.json file and save it in a .settings/ folder. This file is how the TypeScript compiler knows how to behave. There'll be lots of tasks commented out depending on if you're using "gulp" or "jake" or whatever's the flavour of the month of whatever that is, but you're only interested in the first one. Set it to something like this:

// Compiles a TypeScript program
{
	"version": "0.1.0",
	
	// The command is tsc. Assumes that tsc has been installed using npm install -g typescript
	"command": "tsc",
	
	// The command is a shell script
	"isShellCommand": true,

	// Show the output window only if unrecognized errors occur. 
	"showOutput": "silent",
	
	// The args to pass to the typescript compiler
	"args": ["--out","bin/js/game.js"],
	
	// use the standard tsc problem matcher to find compile problems
	// in the output.
	"problemMatcher": "$tsc"
}

The important line is the "args": ["--out","bin/js/game.js"] one. This is telling TypeScript to compile all our ts files into one js file, and save it as game.js in the bin/js/ folder.

Creating the build task to compile the TypeScript

After you've created your tasks.json file, hit Ctrl+Shift+B again, and watch the spinny thing down in the bottom left do its thing. When it's done, it'll spit out a game.js file full of pure JS. 'Tis magic so it is.

The result of the build

Launching your game

To actually see your game in action, you'll need a local web server. Because of browser security restrictions, you'll want to be loading all your files from the web sandbox, rather than the file sandbox (which is what happens if you just open bin/index.html in a browser). There are multiple ways to get a local server running, including EasyPHP, WAMP, MAMP, or NodeJS. Pick your poison as you wish, but as Visual Studio Code is built with NodeJS support out of the bag, I'll use that one.

The shortcut for launching is F5, so you go ahead and press that.

Visual Studio Code has now created a launch.json file for you in the .settings/ folder:

Creating the launch configuration file

The launch.json file is how you tell it what to actually run, and we're going to tell it to run our NodeJS server. With that in mind, change

"program": "app.js"

to:

"program": "server/server.js"

and

"stopOnEntry": true

to:

"stopOnEntry": false

Setting stopOnEntry to false just means that we won't pause execution of the app as soon as it's launched (which you might want to do if you're debugging).

Modifying the launch configuration file to point to our server file

server/server.js doesn't actually exist yet, so lets create that now.

Installing node-static

sever.js is going to be our simple server, and is how we serve our files (all the JS, images, music, and HTML files in your bin/ folder). The easiest way to create a file server with NodeJS is with something like node-static.

We're going to use npm to download node-static, so open a command line window or bash shell and type:

npm install -g node-static

The -g tells npm to install node-static globally, meaning that it's not linked to any one particular project.

One extra step we need to do after this is add an environment variable so that when you reference it in a require() call, NodeJS will look in the global folder (why it doesn't do this by default, I don't know).

If you're on Windows, open a folder, right-click on your Computer and select Properties. Select Advanced system settings, then Environment Variables, then under System Variables, add a new one with NODE_PATH as the key, and the path to your global installs folder as the value. If you've left it as the default, then it's C:\Users\USER\AppData\Roaming\npm\node_modules.

Adding an environment variable in Windows

Creating our server.js file

We're just going to create a basic NodeJS server which uses node-static to serve our files. Create a new file called server.js and save it in the server/ folder. Copy this text:

// import our modules
var static 	= require( 'node-static' );	// used for serving static files
var http	= require( 'http' );		// default node http server
var port	= 5858;						// NOTE: this is the same port as specified in launch.json

// create our file server config
var file = new static.Server( 'bin', { 	// anything in the bin/ folder is served
	cache:0,							// no cache (only for testing)
	gzip:true							// gzip our assets
});

// create our basic server
http.createServer( function( request, response ) {
	request.addListener( 'end', function() {
		file.serve( request, response ); // any url asked for, just try and serve the file from bin/
	}).resume();
}).listen( port );

The only things to note here are that the port is set the same as in launch.json, and that we're setting the bin/ folder as the folder to serve our files out of. We've also set the cache to 0 so that we don't have any problems with cached files when testing our games.

Creating a simple static file server

Now when we hit F5 again to launch our game, it should create our node app. If it doesn't go to the Debug view (the bug button) and make sure your configuration is selected.

Launching the server so we can test our game

Checking out our game!

Now we can just open up a brower and hit the localhost:5858 url (or 127.0.0.1:5858 if that doesn't work), and we should see our game!

Our game running in the browser

You're now ready to rock with Phaser development!

How can this be made better?

You may have noticed that launching the app wasn't exactly the easiest thing in the world. Coupled with the fact that when your app is running, you can't actually change any source files, it's not an ideal setup.

The only important thing is to build (Ctrl+Shift+B) your TypeScript files to JavaScript - if you have a local web server constantly running in the background, it's probably better than launching one every time you want to test.

Thus, an even easier solution would be to download http-server, which is a stand-alone command line file server. You can launch it by opening a command window and typing:

http-server PATH_TO_PROJECT_FOLDER/bin

which is easily turned into a bat/bash executable file that you can just double-click to run, rather than having to type it every time.

Another point of contention is TypeScripts import code:

/// <reference path="../tsDefinitions/phaser.d.ts" />

I'm not sure I could have come up with a more awkward way of doing it. In a comment? Sure, why not. But XML? Ugh, horrible to type. I need to find a shortcut to automatically add it, because you'll probably find yourself adding it multiple times to every file once your projects start to get a bit bigger.

Another small tweak I made was to add some shortcut keys to make VSC behave a bit more like FlashDevelop. You can get this through File > Preferences > Keyboard Shortcuts. I've added:

[
	{ "key": "ctrl+d",			"command": "editor.action.copyLinesDownAction",
									"when": "editorTextFocus" },
	{ "key": "ctrl+q",			"command": "editor.action.commentLine",
									"when": "editorTextFocus" },
	{ "key": "ctrl+shift+q",	"command": "editor.action.blockComment",
									"when": "editorTextFocus" },
	{ "key": "f4",				"command": "editor.action.goToDeclaration",
									"when": "editorTextFocus" }
]

Which is:

Attached below is the MyProj project folder, containing everything I went over here. Go ahead. Download it. Do it.

Files

Comments

Random Guy

This tutorial works like a charm for me, a first time VS Code and Phaser user. Thanks a lot for writing this!

Alessandro Lioi

I've got a problem with the tasks file. When I press the Ctrl+Shift+B, it doesn't create the "game.js" file. I've also tried using your project and it doesn't work. Can you please help me?

Damian Connolly

Hi Alessandro, the first time you press Ctrl+Shift+B, you should be a little tooltip message at the top of the screen (it's easy to miss), with a message along the lines of No task runner configured. Hit the Configure task button, and VSC should create a tasks.json file in your .settings/ folder. Do you have this file? If yes, then:

  • When you hit Ctrl+Shift+B are you getting *any* js files generated?
  • When you try to build, is there anything in the Errors and Warnings section in the bottom-left of the window (the x and exclamation point)? Both should read 0, otherwise, you've got an error somewhere

If it's still not working, send me your email, and I'll take a look at your project.

Alessandro Lioi

Yes, I have the tasks.json file
VSC doesn't create any .js file.
There aren't any Error or Warning

rm

Alessandro Lioi i had the same problem. Removed "C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.0\;" from the system's PATH and reinstalled typescript and then it worked

Submit a comment

* indicates required