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.
- 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*
- We check to see if the y position of the bullet is no greater then the enemies current y position plus its height.
- 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.
Warning: count(): Parameter must be an array or an object that implements Countable in /home/ryanch6/public_html/wp-includes/class-wp-comment-query.php on line 405