JavaScript Game Development – MDN Breakout | Beginner

Dear reader, if you are beginner to the JavaScript game development than this tutorial for you. You should have basic to intermediate JavaScript knowledge to start this tutorial.

After working through this tutorial you should be able to build your own simple Web game.

Below screen is output of the game, which we are going to develop.

Capture

Before Starting the tutorial, lets understand few terms which I’ve used in the tutorial:

  1. Score Booard
  2. Lives Board
  3. Bricks
  4. Ball
  5. Paddle
  6. Canvas

Game - Copy

Let’s start the code:

Create one file game.html and add canvas tag.

<!DOCTYPE html>
<html>
<head>
<meta charset=”utf-8″ />
<title>JS Game</title>
<style>

* { padding: 0; margin: 0; }

canvas { background: whitesmoke; display: block; margin: 0 auto; }

</style>
</head>
<body>

<canvas id=”game_canvas” width=”880″ height=”520″></canvas>

</body>
</html>

Now we need to start writing the JavaScript code:

  1. First we will declare the variables.

var canvas = document.getElementById(“game_canvas”); //Getting Element By ID
var ctx = canvas.getContext(“2d”);
var ballRadius = 10; // Define Ball radious
var x = canvas.width/2;
var y = canvas.height-30;
var dx = 2;
var dy = -2;
var paddleHeight = 20; //Paddle height
var paddleWidth = 155; //Paddle width
var paddleX = (canvas.width-paddleWidth)/2;
var rightPressed = false; //Right key press
var leftPressed = false; //Left key press
var brickRowCount = 5; //Bricks row count
var brickColumnCount = 3; //Bricks column count
var brickWidth = 157; //Bricks width
var brickHeight = 20; //Bricks height
var brickPadding = 10; //Bricks padding
var brickOffsetTop = 30; //Bricks Offset top
var brickOffsetLeft = 30; //Bricks offset
var score = 0; //Set initial Score to 0
var lives = 3; //Set initial lives to 3

var bricks = []; //Declaring empty bricks array

2. Displaying bricks & event handlers

 

for (c = 0; c < brickColumnCount; c++) {
bricks[c] = [];
for (r = 0; r < brickRowCount; r++) {
bricks[c][r] = {x: 0, y: 0, status: 1};
}
}

//Setting key events to false
document.addEventListener(“keydown”, keyDownHandler, false);
document.addEventListener(“keyup”, keyUpHandler, false);
document.addEventListener(“mousemove”, mouseMoveHandler, false);

 

function keyDownHandler(e) {
if (e.keyCode == 39) {
rightPressed = true;
} else if (e.keyCode == 37) {
leftPressed = true;
}
}
function keyUpHandler(e) {
if (e.keyCode == 39) {
rightPressed = false;
} else if (e.keyCode == 37) {
leftPressed = false;
}
}
function mouseMoveHandler(e) {
var relativeX = e.clientX – canvas.offsetLeft;
if (relativeX > 0 && relativeX < canvas.width) {
paddleX = relativeX – paddleWidth / 2;
}
}

3. Collusion Detection function

//Detecting
function collisionDetection() {
for (c = 0; c < brickColumnCount; c++) {
for (r = 0; r < brickRowCount; r++) {
var b = bricks[c][r];
if (b.status == 1) {
if (x > b.x && x < b.x + brickWidth && y > b.y && y < b.y + brickHeight) {
dy = -dy;
b.status = 0;
score++;
if (score == brickRowCount * brickColumnCount) {
alert(“YOU WIN, CONGRATS!”);
document.location.reload();
}
}
}
}
}
}

4. All Remaining functions

  • Drawing ball
  • Drawing paddle
  • Drawing  bricks
  • Draw score
  • Draw lives
  • Main function

//Drawing a ball
function drawBall() {
ctx.beginPath();
ctx.arc(x, y, ballRadius, 0, Math.PI * 2);
ctx.fillStyle = “orange”; //Ball Color
ctx.fill(); //Ball Fill
ctx.closePath();
}

//Drawing a paddle
function drawPaddle() {
ctx.beginPath();
ctx.rect(paddleX, canvas.height – paddleHeight, paddleWidth, paddleHeight);
ctx.fillStyle = “orange”; //Paddle Color
ctx.fill();//Paddle Fill
ctx.closePath();
}

//Drawing a bricks
function drawBricks() {
for (c = 0; c < brickColumnCount; c++) {
for (r = 0; r < brickRowCount; r++) {
if (bricks[c][r].status == 1) {
var brickX = (r * (brickWidth + brickPadding)) + brickOffsetLeft;
var brickY = (c * (brickHeight + brickPadding)) + brickOffsetTop;
bricks[c][r].x = brickX;
bricks[c][r].y = brickY;
ctx.beginPath();
ctx.rect(brickX, brickY, brickWidth, brickHeight);
ctx.fillStyle = “red”;
ctx.fill();
ctx.closePath();
}
}
}
}

//Displaying score
function drawScore() {
ctx.font = “16px Arial”; //Score font
ctx.fillStyle = “black”;//Score color
ctx.fillText(“Score: ” + score, 8, 20); //Score text
}

//Diisplaying lives
function drawLives() {
ctx.font = “16px Arial”; //Lives font
ctx.fillStyle = “black”; //Lives color
ctx.fillText(“Lives: ” + lives, canvas.width – 65, 20); //lives text
}

//Main Function
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBricks();
drawBall();
drawPaddle();
drawScore();
drawLives();
collisionDetection();

if (x + dx > canvas.width – ballRadius || x + dx < ballRadius) {
dx = -dx;
}
if (y + dy < ballRadius) {
dy = -dy;
} else if (y + dy > canvas.height – ballRadius) {
if (x > paddleX && x < paddleX + paddleWidth) {
dy = -dy;
} else {
lives–;
if (!lives) {
alert(“GAME OVER”);
document.location.reload();
} else {
x = canvas.width / 2;
y = canvas.height – 30;
dx = 3;
dy = -3;
paddleX = (canvas.width – paddleWidth) / 2;
}
}
}

if (rightPressed && paddleX < canvas.width – paddleWidth) {
paddleX += 7;
} else if (leftPressed && paddleX > 0) {
paddleX -= 7;
}

x += dx;
y += dy;
requestAnimationFrame(draw);
}

draw();//Calling a main function

DONE.

Now you can your game.html file.

Code is also available on Github.

Complete game.html file displayed below:

<!DOCTYPE html>
<html>
 <head>
 <meta charset="utf-8" />
 <title>JS Game</title>
 <style>* { padding: 0; margin: 0; } canvas { background: whitesmoke; display: block; margin: 0 auto; }</style>
 </head>
 <body>

<canvas id="game_canvas" width="880" height="520"></canvas>



var canvas = document.getElementById("game_canvas");//Getting Element By ID
 var ctx = canvas.getContext("2d");
 var ballRadius = 10; // Define Ball radious
 var x = canvas.width / 2;
 var y = canvas.height - 30;
 var dx = 2;
 var dy = -2;
 var paddleHeight = 20; //Paddle height
 var paddleWidth = 155; //Paddle width
 var paddleX = (canvas.width - paddleWidth) / 2;
 var rightPressed = false; //Right key press
 var leftPressed = false; //Left key press
 var brickRowCount = 5; //Bricks row count
 var brickColumnCount = 3; //Bricks column count
 var brickWidth = 157; //Bricks width
 var brickHeight = 20; //Bricks height
 var brickPadding = 10; // Bricks padding
 var brickOffsetTop = 30; //Bricks Offset top
 var brickOffsetLeft = 30; //Bricks offset 
 var score = 0; //Set initial Score to 0
 var lives = 3; //Set initial lives to 3

var bricks = []; //Declaring empty bricks array




for (c = 0; c 
 bricks[c] = [];
 for (r = 0; r 
 bricks[c][r] = {x: 0, y: 0, status: 1};
 }
 }

//Setting key events to false
 document.addEventListener("keydown", keyDownHandler, false);
 document.addEventListener("keyup", keyUpHandler, false);
 document.addEventListener("mousemove", mouseMoveHandler, false);




function keyDownHandler(e) {
 if (e.keyCode == 39) {
 rightPressed = true;
 } else if (e.keyCode == 37) {
 leftPressed = true;
 }
 }
 function keyUpHandler(e) {
 if (e.keyCode == 39) {
 rightPressed = false;
 } else if (e.keyCode == 37) {
 leftPressed = false;
 }
 }
 function mouseMoveHandler(e) {
 var relativeX = e.clientX - canvas.offsetLeft;
 if (relativeX > 0 && relativeX 
 paddleX = relativeX - paddleWidth / 2;
 }
 }

//Detecting 
 function collisionDetection() {
 for (c = 0; c 
 for (r = 0; r 
 var b = bricks[c][r];
 if (b.status == 1) {
 if (x > b.x && x  b.y && y 
 dy = -dy;
 b.status = 0;
 score++;
 if (score == brickRowCount * brickColumnCount) {
 alert("YOU WIN, CONGRATS!");
 document.location.reload();
 }
 }
 }
 }
 }
 }

//Drawing a ball
 function drawBall() {
 ctx.beginPath();
 ctx.arc(x, y, ballRadius, 0, Math.PI * 2);
 ctx.fillStyle = "orange"; //Ball Color
 ctx.fill(); //Ball Fill
 ctx.closePath();
 }

//Drawing a paddle
 function drawPaddle() {
 ctx.beginPath();
 ctx.rect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight);
 ctx.fillStyle = "orange"; //Paddle Color
 ctx.fill();//Paddle Fill
 ctx.closePath();
 }

//Drawing a bricks
 function drawBricks() {
 for (c = 0; c 
 for (r = 0; r 
 if (bricks[c][r].status == 1) {
 var brickX = (r * (brickWidth + brickPadding)) + brickOffsetLeft;
 var brickY = (c * (brickHeight + brickPadding)) + brickOffsetTop;
 bricks[c][r].x = brickX;
 bricks[c][r].y = brickY;
 ctx.beginPath();
 ctx.rect(brickX, brickY, brickWidth, brickHeight);
 ctx.fillStyle = "red";
 ctx.fill();
 ctx.closePath();
 }
 }
 }
 }

//Displaying score
 function drawScore() {
 ctx.font = "16px Arial"; //Score font
 ctx.fillStyle = "black";//Score color
 ctx.fillText("Score: " + score, 8, 20); //Score text
 }

//Diisplaying lives
 function drawLives() {
 ctx.font = "16px Arial"; //Lives font
 ctx.fillStyle = "black"; //Lives color
 ctx.fillText("Lives: " + lives, canvas.width - 65, 20); //lives text
 }

//Main Function
 function draw() {
 ctx.clearRect(0, 0, canvas.width, canvas.height);
 drawBricks();
 drawBall();
 drawPaddle();
 drawScore();
 drawLives();
 collisionDetection();

if (x + dx > canvas.width - ballRadius || x + dx 
 dx = -dx;
 }
 if (y + dy 
 dy = -dy;
 } else if (y + dy > canvas.height - ballRadius) {
 if (x > paddleX && x 
 dy = -dy;
 } else {
 lives--;
 if (!lives) {
 alert("GAME OVER");
 document.location.reload();
 } else {
 x = canvas.width / 2;
 y = canvas.height - 30;
 dx = 3;
 dy = -3;
 paddleX = (canvas.width - paddleWidth) / 2;
 }
 }
 }

if (rightPressed && paddleX 
 paddleX += 7;
 } else if (leftPressed && paddleX > 0) {
 paddleX -= 7;
 }

x += dx;
 y += dy;
 requestAnimationFrame(draw);
 }

draw();//Calling a main function
 

</body>
</html>

Thanks.

Leave a comment