Getting started making games with HTML5 canvas is surprisingly easy. All you need is a canvas, some objects to draw on the canvas, and a game loop that depends on requestAnimationFrame.

Configuring a Game Loop

Arguably the most crucial part of a game is its game loop. Within this loop, all of our game logic (drawing, events, collisions, etc.) is repeatedly calculated on each frame. For instance, if we want to make a player move across the screen, we achieve this by repeatedly drawing and erasing the player at a slightly altered position at a quick framerate. All of this is achieved through the game loop (which is why a nice framerate is so important!).

Let's setup a simple loop:

  // cross-browser compatibility
(function(){
    var requestAnimationFrame = window.requestAnimationFrame ||
                                window.mozRequestAnimationFrame ||
                                window.webkitRequestAnimationFrame ||
                                window.msRequestAnimationFrame;
    window.requestAnimationFrame = requestAnimationFrame;
})();

function render() {
    // game logic here
}

// where the magic happens
(function gameLoop(){
    render();
    requestAnimationFrame(gameLoop);
})();

With this loop setup, all that's left is to draw an object to the canvas and render it!

  var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');  // let canvas know we want 2d rendering

// draw a rectangle!
ctx.fillRect(5, 5, 10, 10);

Note that as of now, the above code doesn't need to go in the render() function because it is static. Let's say we want to make our little rectangle player move. To do this, we need to setup some event handlers to grab key input:

  var canvas = document.getElementById('canvas'),
    ctx = canvas.getContext('2d');

// listen for keys to add to keys array
var keys = [];
document.body.addEventListener('keydown', function(e){
    keys[e.keyCode] = true;
});

document.body.addEventListener('keyup', function(e){
    keys[e.keyCode] = false;
});

Here I removed the call to the fillRect() method because we will use it later in drawing our player. For now, all we have is an array that contains all of our key input (keys) and a way to get that key input through the event listeners.

The next step is to create our player character.

  function Player(body){
    this.width = this.height = body;
    this.x = canvas.width/2 - this.width/2;
    this.y = canvas.height-this.height;
    this.speed = 10;
    this.friction = 0.7
    this.vel_x = this.vel_y = 0;
}

This is a very simple version of a player object containing the bare minimum for creating a solid movement system in canvas. Our player will simply be a rectangle that we will repeatedly draw to the canvas. Let's create a load() method to render our player:

  Player.prototype.load = function() {
    ctx.fillStyle = '#2c3e50';
    ctx.fillRect(this.x, this.y, this.width, this.height);    
};

With this method, we are calling the fillRect() method on our canvas to create a rectangle with a set of dimensions, our player's x coordinate, y coordinate, width, and height.

Before we go any further with trying to move our player, let's draw him to the screen.

  var player1 = new Player(60);

function render() {
    // game logic here
    ctx.clearRect(0,0, canvas.width, canvas.height);
    player1.load();
}

All this code does is create an instance of our Player object and call the load() method in the game loop. At this point, you should simply see a rectangle on the canvas like earlier. Next we will add a run() method to our Player object to register movement.

  Player.prototype.run = function() {
    if (keys[37]) {
        if (this.vel_x < this.speed)
            this.vel_x -= 2;
    }
    if (keys[39]){
        if (this.vel_x < this.speed)
            this.vel_x += 2;
    }

    if (this.x <= 0)
        this.x = 0;
    if (this.x >= canvas.width - this.width)
        this.x = canvas.width - this.width;

    this.vel_x *= this.friction;
    this.x += this.vel_x;
};

With the first few lines we check for any events that have taken place and register movement to our player accordingly by incrementing our player's velocity. This velocity is then added to our player's position at the end of the event process. It is important not to forget about the friction parameter for our player, as without it, our player will move infinitely in the direction we indicate.

Finally, add the run() method to the game loop:

  function render() {
    // game logic here
    ctx.clearRect(0,0, canvas.width, canvas.height);
    player1.load();
    player1.run();
}

Now we have a working game!

For the full source, check out this CodePen:


3,176 0 36