Jul 3, 2012

HTML5 Air Hockey Game Using Canvas

Air Hockey, my first HTML5 game

In this tutorial you will be learning the importance of canvas tag.


The canvas element is part of HTML5 and allows for dynamic, scriptable rendering of 2D shapes and bitmap images. It is a low level, procedural model that updates a bitmap and does not have a built-in scene graph.


Working : A puck(ball) will be freely moving in the table, we just need to stop it from touching the horizontal sides of table by using two mallets.

Let's break our game into pieces, which will help us to code easily. We will be using following javascripts

  • jquery.hotkeys.js - Helps for keyboard events

  • key_status.js - Helps to call required event for our game

  • util.js - Helps to define the mallet position

  • game.js - Our main file which will contain the game functionality



First we will make the canvas in our HTML document.



[html]
<canvas id="canvas" width="480" height="320" tabindex="1"></canvas>
[/html]



Now javascript - game.js


[js]
var canvasElement = document.getElementById("canvas");
var canvas = canvasElement.getContext("2d");

var canvas_width = canvasElement.width;
var canvas_height =canvasElement.height;
var botX = 2;
var botY = 2;
var mx = 2;
var my = 4;
var points = 0;

var init = {};
var FPS = {};

FPS.set = 30;
[/js]



Above, first we created a canvas in our HTML document, and then in game.js we are initializing it, storing its height and width in a variable, declaring some more constant variables.

Let's make our players(mallets) and our ball(puck).



[js]
var player = {
color: "#000",
x: 220,
y: 310,
width: 50,
height: 10,
draw: function() {
canvas.fillStyle = this.color;
canvas.fillRect(this.x, this.y, this.width, this.height);
}
};

var player2 = {
color: "#000",
x: 220,
y: 0,
width: 50,
height: 10,
draw: function() {
canvas.fillStyle = this.color;
canvas.fillRect(this.x, this.y, this.width, this.height);
}
};

var ball = {
x : 2,
y : 2,
r : 5,
draw: function() {
canvas.beginPath();
canvas.arc(this.x, this.y, this.r, 0, Math.PI*2, true);
canvas.fill();
}

};
[/js]



We are defining player1 and player2 and setting its height, width, default position and finally giving it a shape.

HTML5 Air hockey

At this stage if you run the code then you will just find a blank canvas element with no players and no ball. Because we just created the players and ball, we have not set them to do something in canvas. So let's do that now.




[js]

init.interval = setInterval(function(){
update();
draw();
}, 1000/FPS.set);


function update() {
if (keydown.left) {
player.x -= 5;
player2.x -= 5;
}

if (keydown.right) {
player.x += 5;
player2.x += 5;
}

player.x = player.x.clamp(0, canvas_width - player.width);

player2.x = player.x.clamp(0, canvas_width - player.width);

}

function draw() {
canvas.clearRect(0, 0, canvas_width, canvas_height);
player.draw();
player2.draw();
ball.draw();

}
[/js]



Now if you run the file then you'll find that in our canvas a ball and two players will present. If you try to press left and right arrow players will move left/right.

HTML5 Air hockey

In our init() function we call two functions draw() and update() in interval. Update function is used to check any movements or changes in our canvas and it sets the value of players and ball. Draw function will take those values and draw it on canvas.

So if suppose you pressed left arrow once, the update function will take the X position of the player, it will update the new position in the player parameters.

Then the draw function will take the new value from player's parameters and then it will update the canvas, so it appears that the player is actually moving.

And also we are limiting our players to go outside the canvas. We use clamp function to check whether the player has touched the boundaries of the canvas.

Now let's move the ball.



[js]
function draw() {
canvas.clearRect(0, 0, canvas_width, canvas_height);
player.draw();
player2.draw();
ball.draw();

if (ball.x + mx > canvas_width || ball.x + mx < 0){
mx = -mx;
}
if (ball.y + my > canvas_height || ball.y + my < 0){
my = -my;
}

ball.x += mx;
ball.y += my;

}

[/js]



We updated our draw function. Here we use if-else conditions to check the position of the ball. If its touching the boundary then throw it back. mx and my are the variables which helps the ball to give X, Y position. And with its help we change the X, Y co-ordinates of the ball every time.

Now if you run the code, the ball will be moving.

HTML5 Air hockey

But it won't be reacting with the players. Now we will update our draw function one more time to check whether our ball is colliding with player1 or player2.



[js]

function collides(a, b) {
if(a.y == b.y || a.y <= b.height){
if(a.x >= b.x && a.x <= b.x+b.width){
return true;
}else{
return false;
}
}

}

function draw() {
canvas.clearRect(0, 0, canvas_width, canvas_height);
player.draw();
player2.draw();
ball.draw();

if (collides(ball, player)) {

my = -my;

}else if (collides(ball, player2)) {

my = +my;

}else
{
if (ball.x + mx > canvas_width || ball.x + mx < 0){
mx = -mx;
}
if (ball.y + my > canvas_height || ball.y + my < 0){
my = -my;
}


}

ball.x += mx;
ball.y += my;

}


[/js]



As you can see we have created one more function collides(), which takes two parameters. In our draw function we are checking whether ball and player1, ball and player2 are colliding with each other. In our collides() function we are checking position of ball and players. If it returns true, then we change the mx and my value.

Now try running the game again, when the ball hits the players it will return back.

HTML5 Air hockey

Last we will code the game over section. If the ball touched the horizontal boundary of canvas then we end our game.



[js]
function gameOver(){
canvas.fillStyle = '#000';
canvas.font = '18px verdana';
canvas.textBaseline = 'top';
canvas.fillText('Game Over, refresh the page to restart game', 50, 150);

clearInterval(init.interval);

$('#level').removeAttr('disabled');
}

if (ball.y + my > canvas_height || ball.y + my < 0){
my = -my;
gameOver();
}
[/js]



We call gameover() function in our draw function. With help of clearInterval() function we stop the game.


HTML5 Air hockey


So this was the basic game, it can't be completely called Air Hockey but after creating it I found that word to be the best. Still there are many bugs. I just started learning HTML5 and this was my first attempt on a game. You can download this from github, suggestions are always welcomed and fork me if you liked it.

2 comments :

  1. Nice, but as with many tutorials of this sort, you completely forgot how to structure the files. You also use a jquery plugin, which needs explanation for setting up. You also failed to show how to cause the page to load the and run the game such as with a call to init();

    ReplyDelete