Basic JS Canvas 2D Game Programming : Game Loop, Draw, Physic and Key Input

On this post I will show you what we can get with canvas and a little javascript code. I will try to implement game loop, game draw,  simple 2D physic, and key input method with this little demo of bouncing ball. on this simple tutorial we using keymaster.js simple micro-library for defining and dispatching keyboard shortcuts in our little project.

Useful Link

Project Files >> Download Here

Game Demo >> See Here

#1 Build your HTML code with canvas tags in it.

First we must create our html file with canvas tags in it, here is our html file example.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>BASIC Canvas Game Part 1</title>
//we need to load keymaster micro library here
<script src="keymaster.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
//Javascript Code goes here
</script>
</head>
<body>
<canvas id="canvas" width="800" height="600" />
<p>Use Arrow Keys to add movement to the ball</p>
</body>
</html>

#2 add global variable and create basic game loop method

Add global variable we would use in this tutorial and define constant or initial value to each variable. There are some variable we would use previousTime, INTERVAL, H, W, GRAVITY, BOUNCY, and key Input (LEFT, UP, RIGHT, DOWN) and avatar as representative of object we would draw. There are 3 main function that we use to create the game loops UPDATE, DRAW, and clearCanvas. Don’t forget to start the game loops when windows OnLoad function, use setInterval function to emulated FPS (frame per second) game loop.

var previousTime = 0,
	INTERVAL = 15,
	W = 800,
	H = 600,
	GRAVITY = 1.5,
	BOUNCY = 0.80,
	avatar,
	LEFT = 37, UP = 38, RIGHT = 39, DOWN = 40;

window.onload = function(){
	//Initial Condition, Get canvas object
	var canvas = document.getElementById("canvas"),
	c = canvas.getContext("2d");
	//Initiate object
	avatar = new Avatar();
	//Set Game Loops
	setInterval(
		function () {
			var currentTime = new Date().getTime(),
				timeElapsed;

			if (previousTime == 0) {
				previousTime = currentTime;
			}

			timeElapsed = currentTime - previousTime;

			update (timeElapsed, currentTime);
			draw (canvas, timeElapsed, currentTime);

			previousTime = currentTime;
		}
	, INTERVAL);
};

function update(timeElapsed, currentTime) {
	//Function to Update game loop here
}

function draw (canvas, timeElapsed, currentTime) {
	//Function to draw object to canvas
}

function clearCanvas(canvas) {
	//Function to clear canvas, called everytime we redraw the canvas
}

function Avatar () {
	//Draw Our Initial Object Here
}

#3 Draw Initial Object

We set our initial object site, color, position and velocity on Avatar() function

function Avatar () {
	this.x = 300;
	this.y = 100;
	this.vx = Math.random() * 10 - 5; // random between -5 and 5
	this.vy = -12;
	this.size = 50;
	this.color = 0x660000 + Math.floor(Math.random() * 255);
}

#4 create basic draw and clear canvas function

We would create basic draw and clear canvas function to implement re-draw object on game loop. always call our object (which we would show on canvas) on draw function. clearCanvas simply clear everything on canvas to be re-draw again on next draw call on game loops.

function draw (canvas, timeElapsed, currentTime) {
	var c = canvas.getContext("2d");
	clearCanvas(canvas);

	// draw avatar
	c.beginPath();
	var r = avatar.size/2;
	c.arc(avatar.x + r, avatar.y + r, r, 0, Math.PI *2);
	c.fillStyle = "#" + avatar.color.toString(16);
	c.fill();

}

function clearCanvas(canvas) {
	var c = canvas.getContext("2d");
	c.beginPath();
	c.rect(0,0,W,H);
	c.fillStyle = "#CCCC99";
	c.fill();
}

#5 Implement game update function with simple physic bouncing and gravity

We would implement game logic on update function. I created simple physic logic where the ball will be bouncy when hit the border and the y-axis velocity will increased based on gravity constant. We also update the ball position on X and Y coordinate based on x and y axis velocity of ball. Whenever the ball hit the border we would reverse ball x, y velocity based on which border the ball hit (Top and Bottom reverse Y velocity, Right and Left reverse X velocity). And don’t forget multiply it with BOUNCY constant to implement loss of momentum for each bounce.

function update(timeElapsed, currentTime) {
	avatar.vy += GRAVITY;
	avatar.x += avatar.vx;
	avatar.y += avatar.vy;

	// constrain avatar to bounds of screen.
	var topBound = 0,
		rightBound = W - avatar.size,
		bottomBound = H - avatar.size,
		leftBound = 0;

	if (avatar.x > rightBound) {
		avatar.x = rightBound;
		avatar.vx *= -1;
		avatar.vx *= BOUNCY;
		avatar.vy *= BOUNCY;
	}
	if (avatar.x < leftBound) {
		avatar.x = leftBound;
		avatar.vx *= -1;
		avatar.vx *= BOUNCY;
		avatar.vy *= BOUNCY;
	}
	if (avatar.y < topBound) { 					
		avatar.y = topBound;
		avatar.vy *= -1;
		avatar.vx *= BOUNCY;
		avatar.vy *= BOUNCY;
	} 		
	if (avatar.y > bottomBound) {
		avatar.y = bottomBound;
		avatar.vy *= -1;
		avatar.vx *= BOUNCY;
		avatar.vy *= BOUNCY;
	}

	if ( Math.abs(avatar.vx) <= 1 &&
		 Math.abs(avatar.vy) <= 1 &&
		 Math.abs(avatar.y - bottomBound) <= 1) {
		avatar.y = bottomBound;

	}

}

#6 Implement Key Input on update function

We would like to add/subtract x or y axis velocity by 3 point each time we press arrow button (depending which arrow you press), just insert code below on update function.

if (key.isPressed(RIGHT)) {                    
	avatar.vx += 3;
}

if (key.isPressed(LEFT)) {
	avatar.vx -= 3;
}

if (key.isPressed(UP)) {
	avatar.vy -= 3;    
}

if (key.isPressed(DOWN)) {
	avatar.vy += 2;    
}

#Final : The complete javascript code

var previousTime = 0,
	INTERVAL = 15,
	W = 800,
	H = 600,
	GRAVITY = 1.5,
	BOUNCY = 0.80,
	avatar,
	LEFT = 37, UP = 38, RIGHT = 39, DOWN = 40;

window.onload = function(){
	var canvas = document.getElementById("canvas"),
		c = canvas.getContext("2d");

	avatar = new Avatar();

	setInterval(
		function () {
			var currentTime = new Date().getTime(),
				timeElapsed;

			if (previousTime == 0) {
				previousTime = currentTime;
			}

			timeElapsed = currentTime - previousTime;

			update (timeElapsed, currentTime);
			draw (canvas, timeElapsed, currentTime);

			previousTime = currentTime;
		}
	, INTERVAL);
};

function update(timeElapsed, currentTime) {
	if (key.isPressed(RIGHT)) {                    
		avatar.vx += 3;
	}

	if (key.isPressed(LEFT)) {
		avatar.vx -= 3;
	}

	if (key.isPressed(UP)) {
		avatar.vy -= 3;    
	}

	if (key.isPressed(DOWN)) {
		avatar.vy += 2;    
	}

	avatar.vy += GRAVITY;
	avatar.x += avatar.vx;
	avatar.y += avatar.vy;

	// constrain avatar to bounds of screen.
	var topBound = 0,
		rightBound = W - avatar.size,
		bottomBound = H - avatar.size,
		leftBound = 0;

	if (avatar.x > rightBound) {
		avatar.x = rightBound;
		avatar.vx *= -1;
		avatar.vx *= BOUNCY;
		avatar.vy *= BOUNCY;
	}
	if (avatar.x < leftBound) {
		avatar.x = leftBound;
		avatar.vx *= -1;
		avatar.vx *= BOUNCY;
		avatar.vy *= BOUNCY;
	}
	if (avatar.y < topBound) { 					
		avatar.y = topBound;
		avatar.vy *= -1;
		avatar.vx *= BOUNCY;
		avatar.vy *= BOUNCY;
	} 		
	if (avatar.y > bottomBound) {
		avatar.y = bottomBound;
		avatar.vy *= -1;
		avatar.vx *= BOUNCY;
		avatar.vy *= BOUNCY;
	}

	if ( Math.abs(avatar.vx) <= 1 &&
		 Math.abs(avatar.vy) <= 1 &&
		 Math.abs(avatar.y - bottomBound) <= 1) {
		avatar.y = bottomBound;

	}

}

function draw (canvas, timeElapsed, currentTime) {
	var c = canvas.getContext("2d");
	clearCanvas(canvas);

	// draw avatar
	c.beginPath();
	var r = avatar.size/2;
	c.arc(avatar.x + r, avatar.y + r, r, 0, Math.PI *2);
	c.fillStyle = "#" + avatar.color.toString(16);
	c.fill();

}

function clearCanvas(canvas) {
	var c = canvas.getContext("2d");
	c.beginPath();
	c.rect(0,0,W,H);
	c.fillStyle = "#CCCC99";
	c.fill();
}

function Avatar () {
	this.x = 300;
	this.y = 100;
	this.vx = Math.random() * 10 - 5; // random between -5 and 5
	this.vy = -12;
	this.size = 50;
	this.color = 0x660000 + Math.floor(Math.random() * 255);
}

That’s all, we already implement some of the basic game development game loop and physic with canvas and javascript. see the complete Game Demo Here and download the Complete Project Files Here

 

One Opinion to this post

  1. Jeffery says:

    You share interesting things here. I think that your blog can go viral easily, but you must give it initial boost and
    i know how to do it, just type in google for – wcnu traffic
    increase

Leave a Reply

Your email address will not be published. Required fields are marked *

Comment moderation is enabled. Your comment may take some time to appear.