Making HTML5 games by someone who knows nothing about making games.

Fleet Command - a HTML5 Game

If your thinking about trying your hand at creating a HTML5 game, but have no game creation experince on which to draw, your probably in the same boat as me. Since, despite this limitation, I decided to start making  a HTML5 game anyway, I thought I may as well post about my experiences in the hope they are useful (or at least interesting) to other people.

My true first attempt to create a HTML5 game was a few months back when I decided I’d start hitting the keyboard and hope something worked. Over the following week  I slowly hacked together the outline of a more-a-less functional but totally unsustainable JavaScript based Asteroids style shoot-em up game. Although it never really went any where, I did  learn some pretty important lessons from the experience. The summarise them:

  • Game loops are important and a set interval doesn’t quite cut it.
  • Object collision is hard – especially if you want to do it accurately and don’t wan’t to kill the computer running it.
  • Geometry – This stuff really does have a use.
  • If you plan to do anything clever with the game, you need to keep performance in mind from the get go. Its very easy to bring stuff to a crawl.
  • Sprites look better than triangles.

Based on this, for my latest attempt at making a game (which is substantially more ambitious) I decided to actually have a proper think at how I planned to develop it. I even went so far as to think up a basic plot and doodle roughly how i wanted it all to look. Aside from this though, one of my first major actions was to have a look at some of the HTML5 Game Development frameworks out there, so as to save myself having to reinvent the wheel for the second time (Granted that for the purpose’s of this analogy my last “wheel” was more oval than circle).

It turns out there are actually  quite a lot of HTML5 Game Development frameworks out there, after trying a few though i ended up selecting Batiste’s Spirte.js to be my starting point. The reasons for this are fairly simple, sprite.js is very lightweight,  it support’s webGL (I’m not actually making use of this, i just think its cool), it includes some great extras such as functions for path finding class & collision detection (which you can include as needed) and even though the documentation is a little sparse, the code is easy to read and there are a load of useful examples included.

After finally deciding to go ahead with the game using sprite.js, I spend a good few hours playing around with it, reading its documentation and taking a look though the examples on offer. One of the first things I noticed was that features such as pausing a game, were actually added by sprite.js out of the box. Additionally there were also handy methods to access user input, load assets in to memory prior to the game starting and a host other other little bits & bobs which help to make starting a new game much less painless.

After getting roughly to grips with the codebase, I decided I may as well start actually building my game. My initial aim was to try and replicate the functionality iIhad managed on my first foray in to HTML5 Game building territory. To do this I started off by creating a new HTML file, set up a basic HTML5 structure  (html,head,body kinda stuff, no real content) and added a JavaScript include to grab sprite.js itself, plus this code in the head:

<script type="text/javascript">
	var bootstrap = function(){
		//Create new Sprite.js Scene (effectively the Canvas that sprite js draws on to)
		var scene = sjs.Scene({'w':window.innerWidth, 'h':window.innerHeight});
		var layer = scene.Layer("game_layer");
		//Load images needed to display (ensure these images exist or it won't load)
		scene.loadImages([
			'ship.png',
	 		'background.png'
			 ],
		 function() {
	 		//Create instance of Engine (class i'm using to run the game)
	 		engine = new Engine(scene, layer);
	 		//Setup game loop via Sprite.js's ticker (calls engine's run method)
	 		ticker = scene.Ticker(function() { engine.run(); });
	 		//Pass ticker to engine
	 		engine.setTicker(ticker);
	 		//Start the ticker
	 		ticker.run();
		});
	}
	//Bootstap Game (when page is loaded)
	window.addEventListener("load", bootstrap, false);
</script>

The job of the above code is pretty much to set sprite.js up and then pass along all the important values to my “engine” class. Once the document has loaded and sprite.js has loaded its required assets, the engine class is instantiated, the ticker is created and finally everything gets set in motion with the call to ticker.run().  The most basic engine class that won’t crash should look something along the lines of:

function Engine(scene, layer){
		//store scene and layer for later
		this.scene = scene;
		this.layer = layer;
		this.ticker = null;
		//Create our sprite
		this.myship = this.scene.Sprite("ship.png",{
			"layer": this.layer, //Layer ship will be displayed in.
			"x": 100, 	//X position of sprite
			"y": 100, 	//Y position of sprite
			"w": 37, 	//width of sprite.
			"h": 75 	//height of sprite.
		});

		//Add set ticker method to Engine
		this.setTicker = function(ticker){
			this.ticker = ticker;
		}

		//Create run method which will be called each time the
		//game loop runs.
		this.run = function(){
			//Apply sprites changes (in this case make
			//it so we can see it)
			this.myship.update();
		}
	}

And running the above code should give you something that looks like this.

If all has gone to plan (it hasn’t died horribly) the next step is to make the game actually do something in its run loop. We can use the built in Inputs() Class to get our inputs from the user. To add this, just add the below code under the “this.layer = layer;’ line in the engine class.

this.inputs = scene.Input();

The addition of the above code now means which can check for “this.inputs.keyboard.up” which will return true whenever the user hits the up arrow (or w) key. The same is true for when the down key is pressed, or the left and right arrow keys. Using this we can start making things happen when these keys are pressed, the simplest form of this I could think of was to simply hook each action up so that it alters ships current position by adding or subtracting from its x and y values. The result being that a user will then be able to move the ship around the game are using their arrow keys.

Once this was done, my updated run method looked much like this:

	this.run = function(){
		//Get ships current x and y.
		nx = this.myship.x;
		ny = this.myship.y;
		//Update it depending on which keys are pressed.
		if(this.inputs.keyboard.left){
			nx -= 2;
		}
		if(this.inputs.keyboard.right){
			nx += 2;
		}
		if(this.inputs.keyboard.up){
			ny -= 2;
		}
		if(this.inputs.keyboard.down){
			ny += 2;
		}
		//Tell the ship
		this.myship.position(nx,ny);
		this.myship.offset(0,0);
		//Apply the changes
		this.myship.update();
	}

Assuming everything went well running you game should now give you somthing along the lines of this.

So, now we have movement, but it isn’t really very space ship like movement. To make the movement a little more “space ship” like, my first action was to change the behaviour of the left and right arrow keys, so that the rotate the ship in a given direction, rather than just move it left or right. To do this,  grab the ships current angle and just add or subtract 2 degree’s depending on which way we want to turn the ship. The code may look like:

	ang = this.myship.angle;
	//Update it depending on which keys are pressed.
	if(this.inputs.keyboard.left){
		ang = (-2*(Math.PI/180))+ang;
	}
	if(this.inputs.keyboard.right){
		ang = (2*(Math.PI/180))+ang;
	}

One thing you probably noticed is the adding 2 degrees is a little more maths heavy than you would have guessed. The reason for this is that sprite.js uses radians rather than degrees to calculate the rotation of the ship. To convert from degrees to radians we need to multiply are degree value by PI/180 and then everything will work as expected. Once we have are 2 degrees in radian form, we simply add it to the current angle value to produce a new value for our ships rotation.

On its own though this won’t do a lot as we still need to tell the sprite we want it to rotate to the angle value we just worked out. To do this simply add the call to the setAngle method, passing it our value, before the sprites update method .update() is run.

this.myship.setAngle(ang);

With the addition of the above code and a little luck your ship should now rotate. The next step is going to be making the ship travel in the right direction when we hit the up button, something that’s going to take a little math to solve. Fortunately the required math has already been calculated, meaning all we need to do is to shove our own values in to the formula below.

new_x += (movement * Math.sin(angle));
new_y += (movment * Math.cos(angle));

So for the purposes of our code, our go forward method should look like: (Keep in mind the Y position is the distance from the top of the canvas, so we need to invert this value for it to make sense in the context of our game)

	nx += (5 * Math.sin(ang));
	ny += (5 * Math.cos(ang))*-1;

We now move in the right direction, but it still seems a little lacking. Whats needed is a way to keep track of momentum and for simplicity sake the easiest way to do this is just add a var called speed outside of the run loop and set it to 0. The next step is then to move the “forward” code out for the forward action and to the main body of the run method, so that it will be called every time the game loop runs. Inside the now empty forward if statments action, add the following code

if(speed < 5) speed = speed+0.5;

This will essentially cause the speed value to be increased when you hit the forward button.(limiting it to a max speed of 5 pixels per game loop.) Additionally you now need to swap the 5 in the moment code to use your speed value instead (or you will constantly be moving at that speed).

Now you have momentum, its also probably also worth adding a way of slowing back down again. The simplest way to do this is to add a little code in to the down arrows action, that does pretty much the exact opposite of the forward keys action. For example

if(speed > 0) speed -= 0.5;

Altogether your run loop should now look something like:

	var speed =0;
	//Create run method which will be called each time the
	//game loop runs.
	this.run = function(){

		//Get ships current x and y.
		nx = this.myship.x;
		ny = this.myship.y;
		ang = this.myship.angle;

		//Update it depending on which keys are pressed.
		if(this.inputs.keyboard.left){
			ang = (-2*(Math.PI/180))+ang;
		}
		if(this.inputs.keyboard.right){
			ang = (2*(Math.PI/180))+ang;
		}
		if(this.inputs.keyboard.up){
			if(speed < 5) speed = speed+0.5;
		}
		if(this.inputs.keyboard.down){
			if(speed > 0) speed -= 0.5;
		}
		nx += (speed * Math.sin(ang));
		ny += (speed * Math.cos(ang))*-1;

		//Tell the ship
		this.myship.position(nx,ny);
		this.myship.setAngle(ang);
		this.myship.offset(0,0);
		//Apply the changes
		this.myship.update();
	}

You can see the full code (so far) in action here.

I’m planning to create a series of posts on HTML5/JavaScript game making when I get the time, so with luck this is just the first of many such articles. Since I covered a lot of the basic set-up in this post, hopefully in my next one I’ll be able to make a little more headway in to the actual meat of the stuff.

You can now view the next tutorial in this series here

Also, if your wondering how the game that inspired this tutorial is going, check out what I’ve got so far here.