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

Build a bouncing-ball demo with HTML5 Canvas: a game loop, drawing, simple 2D physics with gravity and bounce, and keyboard input via keymaster.js.

This tutorial demonstrates fundamental game development concepts using HTML5 Canvas and JavaScript. We will create a bouncing ball demo that incorporates game loop mechanics, drawing functions, 2D physics simulation, and keyboard input handling.

Overview

The example uses Canvas with these core components:

  • Game loop structure with update and draw cycles
  • Simple 2D physics including gravity and collision bouncing
  • Keyboard input response for ball movement control
  • keymaster.js for keyboard handling

Step 1: HTML Setup

Create an HTML file with a canvas element and script references:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>BASIC Canvas Game Part 1</title>
<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>

Step 2: Initialize Game Variables and Loop

Establish global variables for game configuration and create the main game loop using setInterval:

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);
};

Step 3: Define Initial Object Properties

The Avatar function establishes the ball's starting position, velocity, size, and color:

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);
}

Step 4: Implement Drawing Functions

Create canvas rendering and clearing methods:

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();
}

Step 5: Add Physics and Collision Detection

Implement gravity, velocity updates, and boundary collision with bouncing:

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;
	}
}

Step 6: Add Keyboard Input

Integrate arrow key controls to modify velocity inside update():

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;
}

With the loop, drawing, physics, and input combined you have a complete interactive canvas demo: a ball that falls under gravity, bounces off the walls with energy loss, and responds to the arrow keys.