Skip to Content

How to create game with JavaScript?

JavaScript has become one of the most popular programming languages in recent years, especially for web development. Its versatility, ease of use, and cross-platform capabilities make it an ideal language for game development. While more complex games are often created using game engines like Unity or Unreal, JavaScript is more than capable of powering fun, interactive games of all kinds.

In this comprehensive guide, we will walk through everything you need to know to start building games with JavaScript. We will cover the basics of programming with JavaScript, setting up a game development environment, working with essential game development concepts like animation, physics, collision detection, score keeping, and sound effects. By the end, you will have the skills to start creating your own JavaScript-powered games.

Requirements for JavaScript Game Development

To start developing games with JavaScript, you will need:

  • A text editor like Visual Studio Code, Sublime Text, Atom, etc. This will allow you to write and edit JavaScript code files.
  • A modern web browser that supports newer JavaScript APIs and the HTML5 Canvas element. We recommend Google Chrome, Mozilla Firefox, MS Edge, or Safari.
  • A basic understanding of HTML and CSS. Knowledge of how to create web pages will be helpful.
  • Fundamental programming knowledge in JavaScript. You should understand concepts like variables, functions, loops, conditionals, arrays, objects, etc.

No special software or expensive tools are required. The text editor and web browser you likely already have installed are sufficient to start learning and experimenting.

Programming Basics with JavaScript

Before jumping into game development, let’s briefly review some JavaScript programming fundamentals. We won’t cover everything about the language, but highlight key aspects that are especially relevant for game programming.

The Script Tag

JavaScript code must be contained within a

For example:

  <script>

  // JavaScript code goes here
  
  </script>

Variables

Variables allow you to store data in memory to reference later in code:

  let score = 0;

Functions

Functions allow you to encapsulate reusable code:

  function updateScore() {
    score++;
  } 

Conditionals

Conditionals allow you to run code selectively based on boolean conditions:

  if (score > 10) {
    alert("New high score!"); 
  }

Loops

Loops allow you to repeat code execution:

  for (let i = 0; i < 10; i++) {
    updateScore(); 
  }

DOM Manipulation

The DOM (Document Object Model) allows you to manipulate HTML and CSS dynamically:

  let elem = document.getElementById("myElement");
  elem.style.color = "red";

This covers the basic programming concepts you'll need. Let's now set up a development environment to start building the game.

Setting Up a Game Development Environment

We will use HTML, CSS and JavaScript files to build our game. These files need to be hosted on a local development server to be able to access them properly in the browser.

There are a few different options:

  • Use a simple HTTP server like http-server npm package
  • Use an online code playground like JS Bin or CodePen
  • Create the files locally and open them directly in your browser

For this guide, we will use the simple node package http-server to create a local server.

To install:

  npm install --global http-server

Then to run it:

  http-server

This will host the files in the current directory on localhost. We can now create our HTML, CSS and JS files there.

Building Game Graphics

To display graphical elements in our game, we will use the HTML element. This creates a drawable surface that we can manipulate dynamically with JavaScript.

Let's create a canvas element in our HTML file:

<canvas id="gameCanvas" width="800" height="600"></canvas>  

This will create an 800x600 sized surface to draw our graphics on. We can access and get a drawing context from the canvas element using JavaScript:

let canvas = document.getElementById("gameCanvas");
let ctx = canvas.getContext("2d");

The context object has methods like fillRect() and clearRect() that allow us to draw rectangular shapes:

ctx.fillRect(50, 50, 100, 150); // Draw rectangle
ctx.clearRect(60, 60, 80, 130); // Clear rectangle

To animate graphics, we need to clear and redraw the shapes repeatedly in quick succession. This is done by defining a render loop:

function render() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  
  // Draw game objects
  
  requestAnimationFrame(render);
}

render();

The render function clears the canvas, draws the scene, and then calls requestAnimationFrame() to schedule itself to run again for the next frame. This creates a loop to animate at 60 FPS.

Besides primitive shapes, we can load images and videos to display sprites, textures, and other complex graphics as well.

Images

let image = new Image();
image.src = "character.png"; 

image.onload = function() {
  ctx.drawImage(image, 200, 200); 
}

Videos

let video = document.createElement("video");
video.src = "animation.mp4";
video.load(); 

video.oncanplay = function() {
  ctx.drawImage(video, 300, 300);
}  

With these basics, you can start building up graphics and animations for your game!

Implementing Game Physics

To make elements move realistically in the game, we need to implement physics simulations. This handles gravity, acceleration, velocity, bouncing, collisions, and other behaviors following the laws of physics.

We will use a simple vector-based approach and define a Physics class to encapsulate the simulation logic:

class Physics {
  constructor() {
    this.gravity = 0.1;
  }
  
  update() {
    // Update objects
  }
}

let physics = new Physics();

Game objects that participate in the physics simulation will have properties like position, velocity and bounding box:

class GameObject {
  constructor() {
    this.position = {
      x: 0,
      y: 0
    };
    
    this.velocity = {
      x: 0,
      y: 0
    };
    
    this.bounds = {
      x: 0,
      y: 0, 
      width: 50,
      height: 50
    };
  }
}

The update() method applies acceleration, velocity, and position updates:

update() {

  // Apply gravity
  objects.forEach(obj => {
    obj.velocity.y += this.gravity;
  });
  
  // Update velocities
  objects.forEach(obj => {
    obj.position.x += obj.velocity.x;
    obj.position.y += obj.velocity.y;
  });
  
  // Handle collisions
  
  // ...
  
}

This allows basic free falling, bouncing, and sliding behaviors. More advanced techniques can simulate springs, ropes, aerodynamics, and other effects.

The Matter.js physics engine is a great option for more robust physics. But even simple simulations can enable satisfying mechanics.

Detecting Collisions

Collision detection is vital for handling bounces, obstacles, triggers, collectibles, and more. We need to know when game objects overlap to respond accordingly.

There are a few approaches for detecting collisions:

Bounding Box Overlap

Check if two bounding boxes intersect:

function checkCollision(obj1, obj2) {

  let xOverlap = 
    obj1.bounds.x  obj2.bounds.x;

  let yOverlap =
    obj1.bounds.y  obj2.bounds.y;  

  return xOverlap && yOverlap;
}

Circle Collision

Calculate distance between two object centers:

function checkCollision(obj1, obj2) {

  let dx = obj1.x - obj2.x;
  let dy = obj1.y - obj2.y;
  let distance = Math.sqrt(dx * dx + dy * dy);

  return distance 

Polygon Collision

Use a physics library like Matter.js to handle complex polygon shapes.

The best approach depends on the game. Bounding boxes are fast and simple. Circles are great for smooth collisions. Polygons allow pixel-perfect precision.

Implementing Scoring

Most games involve keeping track of scores to provide a sense of progress. Let's see how to add scoring mechanics with JavaScript.

First, set up a variable to store the score:

  let score = 0;

Then increment it when game events occur that should award points:

  function handleCollision() {
    score++;
    showScore();
  }

Update the UI to display the current score:

  function showScore() {
    document.getElementById("score").innerText = score;
  }  

You can keep track of the high score across sessions using localStorage:

  function setHighScore() {
    let highScore = localStorage.getItem("highScore") || 0;
    
    if (score > highScore) {
      localStorage.setItem("highScore", score);
    }
  }

And show it on the screen:

  let highScore = localStorage.getItem("highScore");
  
  document.getElementById("highScore").innerText = highScore;

For multiplayer games, keep scores in arrays and sort to show ranking.

With these fundamentals, you can build scoring suited for any type of game!

Adding Sound Effects and Music

Audio is an important part of games for feedback, ambience, and fun. Playing sound effects and background music engages the player and brings games to life.

The Web Audio API provides powerful tools for audio playback and manipulation. Let's look at how to load and play sounds.

Loading Sounds

First, create AudioContext and BufferSource objects:

  let context = new AudioContext();
  let buffer = null;

Load sound files into memory using fetch():

  fetch("sounds/jump.wav")
    .then(res => res.arrayBuffer())
    .then(arrayBuffer => context.decodeAudioData(arrayBuffer)) 
    .then(decodedData => buffer = decodedData);

Playing Sounds

Create a source, set the buffer, connect to speakers and play:

  let source = context.createBufferSource();
  source.buffer = buffer;
  source.connect(context.destination);
  source.start();

Optionally add effects like reverb and panning:

  let reverb = context.createConvolver();

  source.connect(reverb);
  reverb.connect(context.destination);  

For background music use the

  let music = new Audio("music.mp3");
  music.loop = true;
  music.play();

With this foundation you can add immersive sound to enhance gameplay!

Optimizing Performance

Games require high frame rates for smooth gameplay. Here are some tips for optimizing performance in JavaScript games:

  • Use requestAnimationFrame() for rendering instead of setInterval() to avoid frame drops.
  • Limit rendering to 60 FPS maximum to conserve CPU usage.
  • Minimize DOM access which can be slow. Cache frequently used elements.
  • Use Canvas instead of DOM for rendering when possible - it's much faster.
  • Optimize images by using sprite sheets, lowering quality, and removing unused images.
  • Simplify physics and collision logic as much as possible while maintaining functionality.
  • Be careful with object creation and destruction. Object pools can help.
  • Profile CPU usage and optimize hot spots. Look for unnecessary operations.

By following best practices and profiling regularly, you can keep gameplay speed optimal across devices.

Conclusion

Congratulations, you now have all the core skills needed to start building games with JavaScript! The key concepts we covered include:

  • Rendering graphics and animation using Canvas
  • Implementing physics simulations for realistic movement
  • Handling collisions between game objects
  • Tracking scores using variables and localStorage
  • Playing sound effects and music with the Web Audio API
  • Optimizing performance using requestAnimationFrame() and other techniques

With this foundation, you can start taking your game ideas and making them a reality. JavaScript offers the capabilities of a full-featured game development platform that works seamlessly across all browsers and devices. The vibrant community ensures there are plenty of resources to continue exploring.

Some ideas to get started:

  • Create a simple arcade shooter game with sprite animations and physics
  • Build an interactive puzzle game with drag and drop objects
  • Make a classic brick breaker game with canvas rendering and collision detection
  • Develop a platformer using tilemaps and a game engine like Phaser

The possibilities are endless. Keep pushing your JavaScript skills, learn from other games, and have fun building your own games!