The Legend of Canvas

Recreating the Legend of Zelda
in HTML5 Canvas & JavaScript

Fluent 2016 - San Francisco, CA

Created by Rich McLaughlin / Available on GitHub

About Me

Sr. Software Engineer - Vertafore
JS Game Developer - Anonymous Function

HEY! LISTEN!

Slides: tinyurl.com/fluentzelda

Play: Zelda

Code: GitHub

Read: AirPair

Inventory

  • Basic Canvas
  • Drawing to Canvas
  • Map Background
  • Game Loop
  • Sprites
  • Collision Detection
  • Game Genie

Basic Canvas





                    

Drawing to Canvas


var canvas = document.getElementById("zelda");
var context = canvas.getContext("2d");

context.fillStyle = "green";
context.fillRect(10, 10, 100, 100); // x, y, w, h
                    

Map Background



                    

The background image has no real effect on the game.

Collision Detection

- Environmental -

Each screen is broken up into 16 x 16 squares
Each square has a value to represent its interaction

Movement Map
Map Editor Demo

Game Loop


//Usually 60fps
var gameLoop = function () {
    requestAnimationFrame(gameLoop);
};

gameLoop();
                    

This provides a consistent interval to update the game state.
For each iteration we update and draw each object.

Demo

GAME BODIES


var OldMan = function (game, center) {
  this.id = "old-man";
  this.game = game;
  this.size = { x: 16, y: 16 };
  this.center = { x: center.x, y: center.y };
};

OldMan.prototype = {
  draw: function (screen) {
    var x = this.center.x, y = this.center.y;
    var img = document.getElementById(this.id);
    screen.drawImage(img, x - this.size.x / 2, y - this.size.y / 2);
  },
  update: function () { }
};
                    

GAME BODIES


// Example from the sword cave
{
    text: "IT'S DANGEROUS TO GO\nALONE! TAKE THIS.",
    bodies: [
        new CaveFire(game, { x: 80, y: 72 }),
        new CaveFire(game, { x: 176, y: 72 }),
        new OldMan(game, { x: 128, y: 72 }),
        new Sword(game, { x: 128, y: 100 })
    ]
}
                    

Sprites

Sprites have no effect

Each body has a center and size

The sprite is drawn at the body's center

The sprite chosen is based on its state

Collision Detection

- Items/Enemies -

Each object has a center point, width, and height.
For each game loop, we iterate over all objects and determine which collide based on their sizes


//example
player.size = { x: 16, y: 16 };
player.center = { x: 128, y: 88 };

redOctorok.size = { x: 14, y: 14 };
redOctorok.center = { x: 118, y: 88 };
                        

Game Genie

Many classic game codes were added for testing.

↑ ↑ ↓ ↓ ← → ← → B A

THIS ENDS THE STORY

fluentconf.slack.com @Rich

Slides: tinyurl.com/fluentzelda