JavaScript Game Development: Building a 2D Game Engine

JavaScript is a versatile programming language that can be used for various applications, including game development. In this article, we will dive into the exciting world of JavaScript game development and explore the process of building a 2D game engine. We will provide code examples with explanations and showcase their output to help you understand the concepts better.

Understanding the Basics

Before we begin building our game engine, let's familiarize ourselves with some fundamental concepts of game development. In a 2D game, we typically deal with objects, sprites, game loops, and collision detection.

  • Objects ? Objects represent the various entities in our game, such as players, enemies, or obstacles. They have properties like position, size, and velocity.

  • Sprites ? Sprites are the visual representation of objects. They are images or animations that give life to the game's elements.

  • Game Loop ? A game loop is a continuous process that updates the game state and renders the graphics. It typically consists of an update phase, where we update the positions and properties of objects, and a render phase, where we draw the updated game state.

  • Collision Detection ? Collision detection determines if two or more objects have intersected. It is crucial for handling interactions between game entities.

Building the 2D Game Engine

Now that we understand the basics, let's start building our 2D game engine step by step. We'll focus on creating a simple game engine that handles object management, rendering, and basic collision detection.

Step 1: Setting Up the Canvas

We begin by creating an HTML file with a canvas element that will serve as the game's display area:

<!DOCTYPE html>
<html>
<head>
   <title>2D Game Engine</title>
   <style>
      canvas {
         border: 1px solid #000;
         display: block;
         margin: 20px auto;
      }
   </style>
</head>
<body>
   <canvas id="gameCanvas" width="800" height="600"></canvas>
   <script>
      // Game engine code will go here
      const canvas = document.getElementById('gameCanvas');
      const ctx = canvas.getContext('2d');
      
      // Fill canvas with a background color to show it's working
      ctx.fillStyle = '#f0f0f0';
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      
      // Display setup message
      ctx.fillStyle = '#333';
      ctx.font = '24px Arial';
      ctx.textAlign = 'center';
      ctx.fillText('Game Canvas Ready!', canvas.width/2, canvas.height/2);
   </script>
</body>
</html>

Step 2: Initializing the Game Engine

In our JavaScript code, we start by initializing the game engine. We set up the canvas and obtain the drawing context to manipulate the graphics. Additionally, we define an array to store the game objects.

// Initialize the game engine
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const gameObjects = [];

// Game state variables
let lastTime = 0;
const targetFPS = 60;

Step 3: Creating the GameObject Class

Next, we define a GameObject class to represent game entities. Each object will have a position, size, color, and methods for updating and drawing:

class GameObject {
   constructor(x, y, width, height, color = '#ff0000') {
      this.x = x;
      this.y = y;
      this.width = width;
      this.height = height;
      this.color = color;
      this.velocityX = 0;
      this.velocityY = 0;
   }

   update(deltaTime) {
      // Update position based on velocity
      this.x += this.velocityX * deltaTime;
      this.y += this.velocityY * deltaTime;
      
      // Keep object within canvas bounds
      this.x = Math.max(0, Math.min(this.x, canvas.width - this.width));
      this.y = Math.max(0, Math.min(this.y, canvas.height - this.height));
   }

   draw() {
      ctx.fillStyle = this.color;
      ctx.fillRect(this.x, this.y, this.width, this.height);
   }
}

Step 4: Adding Objects to the Game

We can now add objects to the game by creating instances of the GameObject class and pushing them into the gameObjects array:

// Create game objects
const player = new GameObject(100, 250, 50, 50, '#0066cc');
const enemy = new GameObject(600, 200, 40, 40, '#cc0000');
const obstacle = new GameObject(400, 300, 80, 30, '#666666');

// Add objects to the game
gameObjects.push(player, enemy, obstacle);

Step 5: Implementing the Game Loop

To make our game interactive, we need a game loop that updates and renders the game objects continuously. We use requestAnimationFrame for smooth animation:

// Keyboard input handling
const keys = {};

document.addEventListener('keydown', (event) => {
   keys[event.key] = true;
});

document.addEventListener('keyup', (event) => {
   keys[event.key] = false;
});

// Game object class
class GameObject {
   constructor(x, y, width, height, color = '#ff0000') {
      this.x = x;
      this.y = y;
      this.width = width;
      this.height = height;
      this.color = color;
      this.speed = 200; // pixels per second
   }

   update(deltaTime) {
      // Handle player movement
      if (keys['ArrowLeft'] || keys['a']) {
         this.x -= this.speed * deltaTime;
      }
      if (keys['ArrowRight'] || keys['d']) {
         this.x += this.speed * deltaTime;
      }
      if (keys['ArrowUp'] || keys['w']) {
         this.y -= this.speed * deltaTime;
      }
      if (keys['ArrowDown'] || keys['s']) {
         this.y += this.speed * deltaTime;
      }
      
      // Keep within canvas bounds
      this.x = Math.max(0, Math.min(this.x, canvas.width - this.width));
      this.y = Math.max(0, Math.min(this.y, canvas.height - this.height));
   }

   draw() {
      ctx.fillStyle = this.color;
      ctx.fillRect(this.x, this.y, this.width, this.height);
   }
}

// Initialize game
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const gameObjects = [];

// Create player
const player = new GameObject(100, 250, 50, 50, '#0066cc');
gameObjects.push(player);

let lastTime = 0;

function gameLoop(currentTime) {
   const deltaTime = (currentTime - lastTime) / 1000; // Convert to seconds
   lastTime = currentTime;
   
   // Clear canvas
   ctx.fillStyle = '#f0f0f0';
   ctx.fillRect(0, 0, canvas.width, canvas.height);
   
   // Update and draw all objects
   gameObjects.forEach(object => {
      object.update(deltaTime);
      object.draw();
   });
   
   // Draw instructions
   ctx.fillStyle = '#333';
   ctx.font = '16px Arial';
   ctx.textAlign = 'left';
   ctx.fillText('Use Arrow Keys or WASD to move', 10, 30);
   
   requestAnimationFrame(gameLoop);
}

// Start the game
requestAnimationFrame(gameLoop);

Step 6: Adding Collision Detection

Let's add basic collision detection to make our game more interactive:

class GameObject {
   // ... existing code ...
   
   // Check collision with another object
   checkCollision(other) {
      return this.x < other.x + other.width &&
             this.x + this.width > other.x &&
             this.y < other.y + other.height &&
             this.y + this.height > other.y;
   }
   
   // Handle collision response
   onCollision(other) {
      // Override in subclasses for specific behavior
      console.log('Collision detected!');
   }
}

// In the game loop, add collision checking:
function checkCollisions() {
   for (let i = 0; i < gameObjects.length; i++) {
      for (let j = i + 1; j < gameObjects.length; j++) {
         if (gameObjects[i].checkCollision(gameObjects[j])) {
            gameObjects[i].onCollision(gameObjects[j]);
            gameObjects[j].onCollision(gameObjects[i]);
         }
      }
   }
}

Game Engine Architecture

Here's a visual representation of our game engine structure:

Game Engine Structure Input Handler (Keyboard) Game Objects (Player, Enemies) Collision System (Detection) Update Loop (Game Logic & Physics) Render Loop (Canvas Drawing) HTML5 Canvas (Display Output)

Complete Working Example

Here's a complete working example that demonstrates all the concepts:

<!DOCTYPE html>
<html>
<head>
   <title>2D Game Engine Demo</title>
   <style>
      body { margin: 0; padding: 20px; font-family: Arial, sans-serif; }
      canvas { border: 2px solid #333; display: block; margin: 20px auto; }
      .controls { text-align: center; margin: 10px 0; }
   </style>
</head>
<body>
   <div class="controls">
      <h3>2D Game Engine Demo</h3>
      <p>Use Arrow Keys or WASD to move the blue square. Avoid the red enemy!</p>
   </div>
   <canvas id="gameCanvas" width="800" height="400"></canvas>
   
   <script>
      const canvas = document.getElementById('gameCanvas');
      const ctx = canvas.getContext('2d');
      const keys = {};
      
      // Keyboard handling
      document.addEventListener('keydown', (e) => keys[e.key] = true);
      document.addEventListener('keyup', (e) => keys[e.key] = false);
      
      class GameObject {
         constructor(x, y, width, height, color, speed = 150) {
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
            this.color = color;
            this.speed = speed;
         }
Updated on: 2026-03-15T23:19:01+05:30

2K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements