Rss feed

Posts Tagged ‘sprite.js’


Making HTML5 games by someone who knows nothing about making games: Part 2

Tank combat Screenshot

Tank Combat

Hello, welcome to the (somewhat overdue) second part of my “Making HTML5 games by someone who knows pretty much nothing about making games” series. If you’ve not read the first part ( see here ) then it’s probably a good idea to check that out first as the plan is to try and continue from where I left off. If you want to jump right in you can grab a copy of the code produced previously here.

So, just as a recap, the “game” if it can be called that at this stage is being build using the Sprite.js framework and currently consists of a black screen and an ugly looking triangle, which can be controlled using both the arrow and wasd keys. In order to try and bring the “game” closer to something worthy of that description, the next logical step is to start adding a few more features to our game. Shooting, bad guys, stuff like that.

To do this, its probably a good idea to figure out exactly what kind of game we are planning to make, and thus which features its going to need. In the previous tutorial, I’d kinda been thinking of creating a space style shooter, although, to be honest, I don’t really think the movement method fits to well with that. Additionally, I feel like trying something a bit different.

So what’s the new plan?

Tank Combat

Use a tank to fight off the evil alien invaders.

The main aim of this tutorial is to create the above game, with the following four key features;

  • The ability to drive the tank with the arrow and wasd keys.
  • The ability to aim and shoot using the mouse.
  • To have some sort of enemy to fight.
  • To have some graphics that actually fit the new game idea.

Given this, I think the first step is to start bringing our existing “game” into line with the new vision.
To start, I’ve created a new “tank” sprite (just a really basic pixel tank).

Tank Sprite

The tank sprite consist’s of three panels. The first two display the tank body at different stages of movement (basically the tracks move slightly) and the third shows the tanks gun turret, which needs to be separate from the hull so we can position and rotate it separately.

To add the sprite into the game, we will need to update our “ship” sprite definition. I will also rename “ship” to “tank” while here, just to avoid confusion (remember in addition to changing the sprite file, its also important to update the sprite definition with the new sprites width and height).

tank = this.mytank = this.scene.Sprite("tank.png",{
	"layer": this.layer, //Layer tanks will be displayed in.
	"x": 100, 	//X position of sprite
	"y": 100, 	//Y position of sprite
	"w": 36, 	//width of sprite.
	"h": 59 	//height of sprite.
});

To go with the new sprite, you may also want to change the game’s background colour from black to green (like grass) so it fits a little better with the new theme.

Although the tank sprite is now in the game, it’s movement still feels a little wrong, since it was originally set up on the premise that we were going to be controlling a space ship. Because of this I think its worth spending a little time tweaking the way our sprite moves. To start friction plays a much bigger role when not in space, so to replicate this I’ve added an else, to slow the tank down when not accelerating and, in addition I also lowered the acceleration speed from 0.5 to +0.2.

if(this.inputs.keyboard.up){
	if(speed<5) speed = speed+0.2;
}else{
	//Apply friction
	if(speed>0) speed = speed-0.1;
}

While we are playing with movement, it’s also a good time to add some code to stop the tank from constantly flying of the screen as you drive around. To do this, in its simplest form, we just need to add some code that will check whether or not the x & y coordinates the tank is moving too are within the current scene (on screen) and if not, stop that movement from being applied.

To do this add something along the lines of this just above where the new tank position and angle are applied to the sprite (above the comment “//Tell the tank”).

	//Ensure new X position is inside playable area
	if(nx < 0 || (nx + this.mytank.w) > this.layer.w){
		nx = this.mytank.x;
	}
	//Ensure new Y position is inside playable area
	if(ny < 0 || (ny + this.mytank.h) > this.layer.h){
		ny = this.mytank.y;
	}

With a little luck you should find that you are no longer able to drive your tank outside of the game area. While this gets the job done, it (for me at least) feels a little clunky. My solution to this was simply to swap the outright stop effect for a simple bounce effect instead. The new code looks as follows:

	//Ensure new X position is inside playable area
	if(nx < 0 || (nx + this.mytank.w) > this.layer.w){
		speed = -(speed*0.4);
		nx = this.mytank.x;
	}
	//Ensure new Y position is inside playable area
	if(ny < 0 || (ny + this.mytank.h) > this.layer.h){
		speed = -(speed*0.4);
		ny = this.mytank.y;
	}

It works in a very similar way to the simple stop, except rather than simply stopping the ship it also reverses the ship’s momentum at the same time.

Now that it is possible for the tank to have negative momentum, we need to ensure we still apply friction as the current system is only doing this for positive speed.  To achieve this, add a check for “is speed is less than zero” and if so add to our speed until it reaches zero again.

if(this.inputs.keyboard.up){
	if(speed>0) speed = speed-0.1;
	if(speed<0) speed = speed+0.1;
}

The conversion of our existing “space game” into a “tank” game is now nearly complete. To finish off the conversion, we just need to give our tank its turret.

Adding the turret in a basic way should be fairly simple, so for now, let’s just create a new sprite object to be the turret (ensuring we have the correct offsets so that the turret part of our sprite image is all that is visible).

turret = this.myturret = this.scene.Sprite("tank.png",{
	"layer": this.layer, //Layer tanks will be displayed in.
	"x": 100, 	//X position of sprite
	"y": 100, 	//Y position of sprite
	"w": 36, 	//width of sprite.
	"h": 59, 	//height of sprite.
	"xoffset":75,
	"yoffset":0,
	});

Once that is done, we then need to add some code to keep our turret’s position in sync with the main tank. Under the “mytank.update();”, add the following code.

this.myturret.position(nx,ny);
this.myturret.setAngle(ang);
this.myturret.update();

With a little luck you should now have something along the lines of this:

The next step is to give our tank the ability to aim it’s turret, so when bad guys finally do get added, we can shoot them.

As with the keyboard inputs, getting the mouse position in Sprite.JS is fairly simple and is somthing we can just ask spirte.js’s input object to give us. From this and the tank’s own X,Y coordinates, figuring out which way our turret needs to be angled to fire where we point shouldn’t actually be all that difficult (thanks to a handy little math function called atan2).

//Get center point for the tank
tank_cent_y = this.mytank.y+(this.mytank.h/2);
tank_cent_x = this.mytank.x+(this.mytank.w/2);
//Work out angle that the cursor is from tank.
cursorAngle = Math.atan2(
	(this.inputs.mouse.position.y - tank_cent_y),
	(this.inputs.mouse.position.x - tank_cent_x)
 )+1.571;//Add roughly 90 degrees.

Now we have the angle, we can pass it to the “myturrent.SetAngle” method, so that it’s aim will now follow the cursor (instead of just picking up the its angle from the tank hull as it is currently).

this.myturret.setAngle(cursorAngle);

Now we can aim our tank, it makes sense to give it the ability to fire. As with everything else so far, the first thing is to create the missile sprite, for laziness I just went with another quick “paint.exe” job:

 

Missile Sprite

Getting it into the game though, will be a little different to how the tank body/turret were added, as unlike them, chances are we are going to want lots of missiles, not just the one. Thus rather than storing each missile individually, we’ll need to keep track of them in an array.

First,  define a new array to hold all our missiles at the top of the engine object.

this.missiles = [];

Then create a new function we can call every time the tank fires, in order to create us a new missile. For simplicity’s sake I just called mine “fireMissile”.

this.fireMissile = function(){
	//Code here
}

Within this method,  we then want to add the code to generate a new sprite and to store it in to our missiles array.

missile = this.scene.Sprite("missile.png",{
	"layer": this.layer,
	"w":4,
	"h":11,
	"angle": 0,
	"x": 0,
	"y": 0

});
this.missiles.push(missile);

The complex bit here is now going to be working out where the missile  needs to be placed, in order to fire from our tanks turret. Getting the angle is the simplest task as we can just grab it from our turret.

var a = this.myturret.angle;

While the x and y coordinates are a little more complex, as although we could just grab the tanks x and y and use that, a missile suddenly appearing in the middle of the tank and flying out doesn’t really make much scene. Instead, we need to figure out the coordinates of the point thirty or so pixels in front of our tank in the direction that the turret is facing.

To start, we are still going to need to get the centre point.

x = this.mytank.x+(this.mytank.w/2);
y = this.mytank.y+(this.mytank.h/2);

Given that, we can then use the same bit of math we use to calculate tank momentum, in order to figure out where our missile is going to be thirty pixels away from the centre of the tank (travelling in the correct direction). I ended up tweaking this to twenty eight pixels as it seemed to  fit a little better.

My resulting “fireMissile” function ended up looking pretty much like this:

this.fireMissile = function(){
	var a = this.myturret.angle;
	var x = (this.mytank.x+(this.mytank.w/2))+ (28 * Math.sin(a));
	var y = (this.mytank.y+(this.mytank.h/2))+ (28 * Math.cos(a))*-1;
	missile = this.scene.Sprite("missile.png",{
		"layer": this.layer,
		"w":4,
		"h":11,
		"angle": a,
		"x": x,
		"y": y
	});
	this.missiles.push(missile);

}

In order to make clicking actually call the function, you then need to add the following line under the rest of the movement/input code in the run function:

if(this.inputs.mouse.click) this.fireMissile();

At this point you will probably notice that none of the missile sprites added to the game are actually showing up yet, this is because we haven’t yet added a mechanism to update (and therfore draw) the new sprites.

To do this the easiest option is to again create an additioal function, then ensure its called ever time the game loop runs, by adding code such as the following to the bottom of the run function.

this.updateMissiles();

Next you need to create the updateMissiles function in order to give the aforementioned code something to call. Effectively the purpose of the updateMissiles function will be to loop through all missiles contained in the “missiles” array, and apply any updates needed (movement, redrawing etc).

To implement movement, we can use the same technique we used to calculate our missiles initial location (and to move the tank itself around)  in order to calculate the missiles next position. This can then be applied to the sprite before “update()” is called to redraw the sprite in the new location.

this.updateMissiles = function(){
	this.missiles.forEach(function(m){
		var x = m.x+ (6 * Math.sin(m.angle));
		var y = m.y+ (6 * Math.cos(m.angle))*-1
		m.position(x,y);
		m.update();
	});
}

Although this works fine, it’s probably a good idea to add a little bit of functionality to clean up sprites we no longer need, as once a missile leaves the game area there’s not a lot of point keeping it updated, or indeed, in the game at all.

To do this we will need to be able to remove sprites from the “this.missiles” array in engine, meaning we need to ensure the engine is avaible outside the scope of the main game object. (As the .forEach() method will put us in its own scope). To do this simply define a variable called engine above of the engine function.

In order to calculate whether or not we now want to remove a missile, we will need to get it’s x and y position and check they are both above zero and not beyond the width or height of our game area. If it is, we will then want to call “remove()” on the sprite itself and then remove it from our missiles array.

if(!(
	(m.x>0 && m.x < m.layer.w) &&
	(m.y>0 && m.y < m.layer.h)
)){
	m.remove();
	engine.missiles.splice(engine.missiles.indexOf(m),1);
}

Assuming everything has gone to plan, you should now have a game that looks like this:

So we have a tank, we can drive around and can shoot missiles. I guess the next thing on the agenda is to create something to fight. To start I quickly created a new sprite to use as our “bad guy aliens”.

Tank Sprite

Then i added a additional array to our engine object so we have somewhere to keep track of them (essentially they are going to work in much the same way that missiles do now).

Under our “this.missiles” array, add a:

this.monsters = [];

Then create the outline of your new spawnSlug (which is my monster of choice) and updateMonster methods.

this.spawnSlug = function(x,y){
//stuff here
}
this.updateMonsters = function(){
//stuff here
}

Creating a new slug is going to be almost identical to how missiles are created. We just setup our monster sprite and add the result to our” monsters” array.
The angle itself doesn’t really matter so I’ve just set it as one, and the x and y coordinates to spawn our new slug are passed in as parameters.

this.spawnSlug = function(x,y){
	slug = this.scene.Sprite("slug.png",{
		"layer": this.layer,
		"w":16,
		"h":39,
		"angle": 1,
		"x": x,
		"y": y
	});
	this.monsters.push(slug);
}

Since the slug sprite has a few steps of animation, it’s also a good time to make use of Sprite.js’s Cycle method, which essentially allows us to easily animate our sprite using the sprite panel we created. This is done by providing an array of steps, each consisting of the x and y offset we should apply to our Sprite panel and the duration each panel should display for. Once setup the Cycle can then be attached to the slug sprite.

In order to keep track of the new Cycle object, I’ve chosen to store it within the Sprite object itself in an attribute called animation.

//Create slug sprite
this.spawnSlug = function(x,y){
	slug = this.scene.Sprite("slug.png",{
		"layer": this.layer,
		"w":16,
		"h":39,
		"angle": 1,
		"x": x,
		"y": y
	});
	//setup animation.
	slug.animation = scene.Cycle([
		[0,0,5],
		[16,0,5],
		[32,0,5],
		[48,0,5],
		[32,0,5],
		[16,0,5]
	]).addSprite(slug);
	this.monsters.push(slug);
}

Now we can create slug sprites, the next step is to do something with them once they are in the game. As with the missiles this is done by iterating through the list of monsters and applying certain actions to each, before finally updating the sprite. It is useful to note that if you call update on a cycle (as stored in the m.animation) you no longer need to call update on the Sprite itself in order to apply any movement/rotation.

this.updateMonsters = function(){
	//Loop through each monster sprite
	this.monsters.forEach(function(m){
		m.animation.next().update();
	});
}

Now we can start adding some behaviours to our monster, for example making them slowly advance towards the player. Using “atan2″ again, we can  figure out which direction our sprite needs to travel in in order to find our tank (in the same way that we did when working out which direction to point our turret.)

var a = Math.atan2(
	(engine.mytank.y-m.y),
	(engine.mytank.x-m.x)
)+1.571;//90 degrees

Using this angle we can then point our sprite towards the tank and, then using the movement code now powering both the tank itself and it’s missiles, give our monsters the ability to move. The full code may look something like:

this.updateMonsters = function(){
	//Loop through each monster sprite
	this.monsters.forEach(function(m){
		var a = Math.atan2(
			(engine.mytank.y-m.y),
			(engine.mytank.x-m.x)
		)+1.571;
		//Work out new location
		var x = m.x+ (1 * Math.sin(a));
		var y = m.y+ (1 * Math.cos(a))*-1;
		//Apply changes
		m.position(x,y);
		m.setAngle(a)
		m.animation.next().update();
	});
}

In order to test that everything is now working as we expect, we just need to add a little code to our game to spawn the new slug monsters at certain intervals.

if((engine.ticker.currentTick % 200)==0){
	this.spawnSlug(400,-50);
}

The above code will simply add a new slug monster, every 200 ticks of the game loop. Having monsters that want to eat our tank is all well and good, but not a lot of fun if we can’t shoot them. To start, lets add a hp variable to your tank sprite.

this.mytank.hp = 5;

And the same to your monsters, within the spawnSlug method. (I gave mine 2 hp)

slug.hp = 2;

Now comes the hard part, collision detection, fortunately for us, we don’t need to worry to much about this. Sprite.js helpfully comes packaged with its own collision detection system, stored in “lib/collison.js” . Adding this to our game, suddenly adds a host of useful “collidesWith” style methods for detecting collisions (no Math required).

<script type="text/javascript" src='../vendor/lib/collision.js'></script>

To make use of this, navigate back in to your “updateMonsters” method and under the code to apply sprite changes, add:

//Detect collisions
col = m.collidesWithArray(engine.missiles);
if(col !== false){ //false means there were no collisions
	//Take 1 hp away from this monster.
	m.hp--;
	//If monster has less than 1 hp (0), remove it from the game.
	if(m.hp < 1){
		//Remove sprite
		m.remove();
		//remove fictional sprite from our array
		engine.monsters.splice(engine.monsters.indexOf(m),1);
	}
	//remove missile
	col.remove();
	//remove missile from our array
	engine.missiles.splice(engine.missiles.indexOf(col),1);
}

Essentally the above code checks to see whether the current monster has collided with any of the missiles  stored within the missiles array. If no collisions were detected then the “m.collidesWithArray()”  will return false and nothing will happen.

Alternately, if there was a collision between the current monster and a missile, 1 hp is removed from the monster and a check is done to ensure the monsters isn’t dead (if its hp is below 1 (as in 0)), if the monster turns out to be dead, it is then removed from the game. Once this is complete, the missile that hit the monster is then also removed from the game, regardless of whether the monster was killed.

If you play the game now, you should find you are able to shoot the slug monsters as they come towards you. Fun as this is, being invulnerable takes away from the satisfaction, so the next step will be to add a little danger.

Under the above collision code, add:

//Has a monster got to your tank?
col_me = m.collidesWith(engine.mytank);
if(col_me !== false){
	//If so, remove the monster, and take 1hp away from your tank
	m.remove();
	engine.monsters.splice(engine.monsters.indexOf(m),1);
	engine.mytank.hp--;
	//Check to see if the tank is dead?
	if(engine.mytank.hp < 1){
		engine.ticker.pause();
		alert("game over");
	}
}

This code  does the same thing as the previous collision code, except it is checking for collisions between the current monster and your tank, taking away your hp and removing the monster whenever one gets to you. If your tank runs out of hp, “game over” is then triggered by pausing the game loop and displaying a “game over” warning.

Because spawning is currently quite predictable, I think it’s worth adding a slightly better spawning mechanism, just to make the direction the monsters come from a little less predictable, and to additionally add a slowly increasing level of difficulty to the game.

Create a new function called spawnMonster, with code that looks something like;

this.spawnMonster = function(){
	//50% chance of spawning top/bottom or left/right
	if(Math.round(Math.random())==1){
		//If left or right, randomly choose a height to attach
		//our new monster at
		h = Math.floor(Math.random()*this.layer.h);
		if(Math.round(Math.random())==1){
			//attach right
			this.spawnSlug(this.layer.w+50,h);
		}else{
			//attach left
			this.spawnSlug(-50,h);
		}
	}else{
		//if top/bottom, figure out what width to add our sprite
		//at
		w = Math.floor(Math.random()*this.layer.w);
		if(Math.round(Math.random())==1){
			//at bottom
			this.spawnSlug(w,this.layer.h+50);
		}else{
			//at top
			this.spawnSlug(w,-50);
		}
	}
}

The above code essentially flips a coin on whether the monster should spawn at the top/bottom or left/right of the game area. Then depending on which is picked, pick a random position on either the x or y axis (just off screen) to add a sprite. The side the sprite will spawn on is then selected by another coin flip (so to speak).

Once this is done, go to the “run” function and just above where the speed variable is being defined, define a second one and call it spawnrate. Set it to 200. Now within the run method itself, replace the previous monster spawning code with:

//Spawn monster every time tick is a multiple of spawnrate
if((this.ticker.currentTick % spawnrate)==0){
	//If spawn rate is higher than 20, decrese it by 2.
	if(spawnrate>20) spawnrate=spawnrate-2;
	//Spawn a monster somewhere
	this.spawnMonster();
}

The new code will call the this.spawnMonster to create a new slug in a random location, every time the ticker equals a multiple of “spawnrate”. Additionally, each spawn, the time before the next spawn decreases slightly, meaning the monsters will begin to spawn at a faster and faster rate (until the maximum of one every 20 ticks is reached).

To finish off,  make sure to add all the new sprite images to your scene.loadImages back in your bootstrap function, just to avoid the game starting before all sprites have been loaded in to memory.

scene.loadImages([
	'tank.png',
	'slug.png',
	'missile.png',
	 ], function() {

Hopefully, if everything went to plan your game should now look and play something like this:

Now the game is more a less playable and pretty much all our original goals have been completed. I just wanted to add a few final tweaks, that should hopefully make the game that little bit more enjoyable to play. 90% of this change just being the addition of a Score and the visibility of your hp.

To add the HP & score box, I added the following html in to the page (under the game_map div).

<div id='score_board'>
	<div id='score'>0</div>
	<div >Health: <span id='hp'>5</span>/5</div>
</div>

Combined with the following CSS

#score_board {position:absolute;width:100px;right:0;top:0;color:#fff;z-index:9999;}
#score_board div {text-align:center;}
#score{font-size:5em;font-weight:bold;}

This just adds a div on the top right, with a big number to indicate the score and a smaller line of text to tell you your hp. To make both the HP & score counter work, add a score attribute to the main game object (below “this.inputs”).

this.score = 0;

Then in the updateMonsters method, just below where we removed destroyed monsters from the game, add the following code.

engine.score++;
document.getElementById('score').innerHTML = engine.score;

Then, a little further down where hp is being deducted from your own tank (just under “engine.mytank.hp–;”) add

document.getElementById('hp').innerHTML = engine.mytank.hp;

to keep your HP in sync with the UI.

And last but not least, to make the loosing screen a little less annoying, replace the “game over” alert with:

document.body.innerHTML ='<div class="end"><h1>Game Over!</h1><div>Your Score: '+engine.score+'</div></div>';

And add the following bit of additional css to your styles:

.end {
	background-color:#fff;
	color:#000;
	width:400px;
	text-align:center;
	margin-top:50px;
	padding:10px;
}

With that complete, for the purposes of this tutorial. Your done! Congratulation, you should now have a simple tank game that looks more or less like this:

Keep in mind, at this point the game is still really basic, so I encourage you to have a go at developing it further. Just as a few ideas of things you may want to consider adding:

  • Sounds for when firing the cannon, driving and blowing up monsters.
  • More monsters types, and maybe some smarter monster behaviours.
  • High scores?
  • Some terrain, to drive around.
  • Mobile support (Sprite.js) adds some basic stuff for mobile, but the game would benefit a lot from a properly mobile oriented control system.

All code seen in this tutorial and comprising the demos is released as Open Source under the MIT Licence. The source for all demos can be found here.

Thanks for reading,

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.