The HTML5 <canvas> element provides a powerful way to create 2D and 3D games directly in the browser. This guide will help you build interactive HTML5 games using the Canvas API, with detailed examples, exercises, and quiz questions.
What is the HTML5 Canvas?
The <canvas> element is a container for graphics that allows you to draw shapes, text, images, and animations using JavaScript.
Basic Canvas Syntax
<canvas id=”gameCanvas” width=”800″ height=”600″></canvas>
<script>
const canvas = document.getElementById(“gameCanvas”);
const ctx = canvas.getContext(“2d”); // 2D rendering context
</script>
Canvas API Overview
- Drawing Shapes:
- Rectangles: fillRect, strokeRect, clearRect
- Paths: beginPath, moveTo, lineTo, arc
- Drawing Text:
- fillText, strokeText
- Working with Images:
- drawImage
- Animation:
- requestAnimationFrame
Step-by-Step: Build a Simple Game
Example: Bouncing Ball Game
- HTML Structure
<canvas id=”gameCanvas” width=”800″ height=”600″ style=”border:1px solid #000;”></canvas>
- JavaScript Code
const canvas = document.getElementById(“gameCanvas”);
const ctx = canvas.getContext(“2d”);
// Ball properties
let ballX = canvas.width / 2;
let ballY = canvas.height / 2;
let ballRadius = 10;
let ballSpeedX = 3;
let ballSpeedY = 3;
// Animation loop
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear the canvas
// Draw the ball
ctx.beginPath();
ctx.arc(ballX, ballY, ballRadius, 0, Math.PI * 2);
ctx.fillStyle = “blue”;
ctx.fill();
ctx.closePath();
// Move the ball
ballX += ballSpeedX;
ballY += ballSpeedY;
// Bounce off walls
if (ballX + ballRadius > canvas.width || ballX – ballRadius < 0) {
ballSpeedX = -ballSpeedX;
}
if (ballY + ballRadius > canvas.height || ballY – ballRadius < 0) {
ballSpeedY = -ballSpeedY;
}
requestAnimationFrame(draw); // Call the next frame
}
// Start the game
draw();
Game Mechanics
1. Keyboard Input
document.addEventListener(“keydown”, handleKeyDown);
function handleKeyDown(event) {
if (event.key === “ArrowUp”) {
console.log(“Move Up”);
} else if (event.key === “ArrowDown”) {
console.log(“Move Down”);
}
}
2. Collision Detection
Detect collisions between the ball and a paddle or other objects.
function detectCollision(ballX, ballY, paddleX, paddleY, paddleWidth, paddleHeight) {
return (
ballX > paddleX &&
ballX < paddleX + paddleWidth &&
ballY > paddleY &&
ballY < paddleY + paddleHeight
);
}
3. Paddle Movement
let paddleX = canvas.width / 2 – 50;
const paddleWidth = 100;
const paddleHeight = 10;
document.addEventListener(“mousemove”, (event) => {
const rect = canvas.getBoundingClientRect();
paddleX = event.clientX – rect.left – paddleWidth / 2;
});
function drawPaddle() {
ctx.fillStyle = “black”;
ctx.fillRect(paddleX, canvas.height – paddleHeight, paddleWidth, paddleHeight);
}
Complete Game Example: Paddle and Ball Game
<canvas id=”gameCanvas” width=”800″ height=”600″ style=”border:1px solid #000;”></canvas>
<script>
const canvas = document.getElementById(“gameCanvas”);
const ctx = canvas.getContext(“2d”);
// Ball properties
let ballX = canvas.width / 2;
let ballY = canvas.height / 2;
let ballRadius = 10;
let ballSpeedX = 3;
let ballSpeedY = 3;
// Paddle properties
let paddleX = canvas.width / 2 – 50;
const paddleWidth = 100;
const paddleHeight = 10;
// Handle paddle movement
document.addEventListener(“mousemove”, (event) => {
const rect = canvas.getBoundingClientRect();
paddleX = event.clientX – rect.left – paddleWidth / 2;
});
// Draw the paddle
function drawPaddle() {
ctx.fillStyle = “black”;
ctx.fillRect(paddleX, canvas.height – paddleHeight, paddleWidth, paddleHeight);
}
// Draw the ball
function drawBall() {
ctx.beginPath();
ctx.arc(ballX, ballY, ballRadius, 0, Math.PI * 2);
ctx.fillStyle = “blue”;
ctx.fill();
ctx.closePath();
}
// Main game loop
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBall();
drawPaddle();
// Move the ball
ballX += ballSpeedX;
ballY += ballSpeedY;
// Ball collision with walls
if (ballX + ballRadius > canvas.width || ballX – ballRadius < 0) {
ballSpeedX = -ballSpeedX;
}
if (ballY – ballRadius < 0) {
ballSpeedY = -ballSpeedY;
}
// Ball collision with paddle
if (
ballY + ballRadius > canvas.height – paddleHeight &&
ballX > paddleX &&
ballX < paddleX + paddleWidth
) {
ballSpeedY = -ballSpeedY;
}
// Game over
if (ballY + ballRadius > canvas.height) {
alert(“Game Over!”);
document.location.reload();
}
requestAnimationFrame(draw);
}
draw();
</script>
Exercises
Exercise 1: Add Score Tracking
Modify the paddle and ball game to track and display the player’s score.
Solution:
let score = 0;
function updateScore() {
score++;
}
function drawScore() {
ctx.font = “16px Arial”;
ctx.fillStyle = “black”;
ctx.fillText(“Score: ” + score, 8, 20);
}
// Update the draw function
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBall();
drawPaddle();
drawScore();
// Ball collision with paddle
if (
ballY + ballRadius > canvas.height – paddleHeight &&
ballX > paddleX &&
ballX < paddleX + paddleWidth
) {
ballSpeedY = -ballSpeedY;
updateScore();
}
// Ball collision with walls
if (ballX + ballRadius > canvas.width || ballX – ballRadius < 0) {
ballSpeedX = -ballSpeedX;
}
if (ballY – ballRadius < 0) {
ballSpeedY = -ballSpeedY;
}
if (ballY + ballRadius > canvas.height) {
alert(“Game Over! Your Score: ” + score);
document.location.reload();
}
ballX += ballSpeedX;
ballY += ballSpeedY;
requestAnimationFrame(draw);
}
Multiple-Choice Questions
Question 1:
Which method is used to draw a filled rectangle on the canvas?
- fillRectangle
- drawRect
- fillRect
- rectFill
Answer: 3. fillRect
Question 2:
What does the clearRect method do?
- Draws a transparent rectangle.
- Clears a rectangle area of the canvas.
- Fills a rectangle with white color.
- Removes the canvas element.
Answer: 2. Clears a rectangle area of the canvas.
Question 3:
Which function is best for animating a game loop?
- setInterval
- setTimeout
- requestAnimationFrame
- drawLoop
Answer: 3. requestAnimationFrame
Best Practices for Canvas Games
- Optimize Redrawing: Use clearRect to avoid overlapping frames.
- Separate Logic: Keep game logic and rendering code modular.
- Use Event Listeners: Handle user input dynamically.
- Test Performance: Ensure smooth frame rates by profiling your game.