Let’s Build a Game! Part 3

July 30th, 2013

Space shooter game screen
Here we go, Part 3, the “Return of the Jedi” for our game. If you have been following along you should be able to just pick it up. If not, check out Part 1 and Part 2. In this final part we will add a few finishing touches. Lets start with something in the background, and an enemy. It will be a simple finish, but it should allow you to expand from there!

Lets start with the background, we will keep it simple and draw some stars in the background. The idea is to randomly draw 50 2×2 pixel particles for our stars. Create a simple function that has a loop in it that will add a new object to a Game.stars array.

Game.stars = [];

Game.createStars = function() {
	var x,y,a;
	for(var i = 0; i < 50; i++){
		x = Math.floor(Math.random() * Game.W);
		y = Math.floor(Math.random() * Game.H);                  
		a = Math.random();	
		Game.stars.push({x:x,y:y,a:a});
	}
};


As you can see. We have 3 variables x, y, a, x and y are pretty straight forward, they are the co-ordinate for our stars! The a is for the alpha. You are able to adjust the alpha(opacity) of the shape you are about to draw to the screen. Which works great for our stars. So as you can see we push an object to the Game.stars array and we are off! Now we have to actually get our stars to the screen. Lets create a function to loop through our now full Game.stars array.

Game.paintStars = function() {
	for(var i = 0; i < Game.stars.length; i++){
		Game.ctx.globalAlpha = Game.stars[i].a;
		Game.ctx.fillStyle = '#ffffff';
		Game.ctx.fillRect(Game.stars[i].x, Game.stars[i].y,2,2);
	}
	Game.ctx.globalAlpha = 1;
};

We loop through our Game.stars and use the values on the object to paint the stars. At the very end of the loop we will reset the globalAlpha to 1 so that when we draw our other elements to the screen they are at full opacity.

In order to get these drawing correctly, we need to call Game.createStars at the beginning of our Game.init function and then the Game.paintStars in the Game.update block.

Game.update = function() {
	//Lets paint the background
	//Set the fill style to be one of those not quite black but cool colors
	Game.ctx.fillStyle = '#273636';
	//Paint the background 
	Game.ctx.fillRect(0,0,Game.W,Game.H);
	Game.paintStars();
	//Paint the player
	Game.player.paint();
	//Check is player keys
     ...

We have to be aware of the order in which we call our various objects to the screen. We call the Game.paintStars after the paint the background. If we do it before we will see nothing because our full width background paint will cover them, so we need to paint our stars on top of that background.

We are in the home stretch now! One the last things we will add to our tiny game is an enemy. We will have the enemy ship appear on the right side of the screen and it will be real simple, shot the enemy!

To start we will create an Game.Enemy constructor object. I will have a few properties and some methods, lets take a look.

Game.Enemy = function() {
	this.x = Game.W - 64;
	this.y = Math.floor(Math.random()*Game.H);
	this.H = 58;
	this.W = 58;
	this.img = new Image();
	this.img.src = "imgs/enemy_ship.gif";
	this.paint = function() {
		Game.ctx.drawImage(this.img,this.x,this.y);
	};
};

Lets add this just under the player object. Our Game.Enemy object has some pretty basic properties, x, y, H, W, img (and a src for that img) and also an paint method. We also need a simple function just to create a new enemy.

Game.enemyMake = function() {
	Game.enemy = new Game.Enemy();
};

Pretty straight forward. Lets start with creating an enemy in our Game.init by running the Game.enemyMake function, that way there is one enemy to begin with. We will create a new enemy every time we hit one. So whenever our bullet hits the enemy ship we will destroy that one and then create a new one.

In Game.player.handleBullets lets add another method to check for collision, lets take a look at it first and then go over it.


collisionCheck: function() {
	for(var i = 0; i < Game.player.bullets.length; i++){
		if(Game.player.bullets[i].y > Game.enemy.y
		&& Game.player.bullets[i].y < Game.enemy.y + Game.enemy.H
		&& Game.player.bullets[i].x > Game.enemy.x
		&& Game.player.bullets[i].x < Game.enemy.x + Game.enemy.W){
			console.log("Hit");
		}
	}
}

Alright, so this is probably one of the more complex parts of this game, but when you look at it, it is not so bad. First we loop through all of the players bullets, for each we check a few things.

  1. Is the y position of the current bullet greater than the y position of the enemy. *Note that position at the top left corner of the canvas is 0,0, this got me a bit when I was first playing around with collision detection and trying to understand it*
  2. We check to see if the y position of the bullet is no greater then the enemies current y position plus its height.
  3. We also do the exact same for the x position, but in this case we check if it is within the width of the enemy.

Add this check just after the Game.player.handleBullets.updateBullets in our Game.update loop. If these conditions are true we have a HIT! Lets work on what happens when we register a hit. If we hit an enemy we should remove the bullet that hit the enemy, and also create a new enemy, overwriting the current one.


Game.player.bullets.splice(i,1);
Game.enemyMake();

Remove the console.log("Hit") and replace it with what is above. We use the splice array method to remove that bullet from the array. We then use Game.enemyMake to create a new enemy. Now try it out! Fire at the enemy and hit him, you will see that a new one reappears somewhere on the screen.

And I think we will stop here, there is a lot more that could be done like, scoring, have the enemy fire back, having waves of enemies, how about a boss battle! The possibilities are endless. Hopefully this gives you a good start at working with canvas and creating some interactions. Keep checking back and there will be some more looks at creating games as I play around some more.

Files can be found on GitHub.