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.