HTML 5 - Programming a game (Live Demo)

HTML 5 - Programming a game (Live Demo)

In this article the development of a simple 2D HTML5 game written with pure Javascript is explained step by step. Elementary knowledge in Javascript is required.

What it looks like at the end

screen1.png

What should it do?

In the game there is a main character that is controlled with the keys W, A, S, D and can fire a fireball with the left mouse button. The goal is to defeat enemy waves that increase with each level.

Todo

  • A background graphic
  • One Character Graphic
  • One fireball graphic
  • An Opponent Graphic
  • Loading graphics
  • Draw graphics
  • Keyboard and mouse recognition Input
  • Firing our fireball in mouse pointer direction
  • Generate enemies
  • Collision and game logic

Our graphics

I have created some simple graphics that are used here for the game. background.png character.png enemy.png shot.png

The basic scaffold

Start with the HTML file (index.html):

<!DOCTYPE html>
<html>
   <head>
   </head>
   
   <body>
      <canvas id="canvas" width="800" height="600">No support</canvas>
      <script type="text/javascript" src="game.js"></script>
   </body>
</html>

The HTML5 document consists mainly of an HTML5 canvas, which we will access later with the included game.js.

We'll get to the preserves. We now create the mentioned Javascript file. The game.js! In this tutorial we only work with one single Javascript file, of course it would make more sense and in the long run with larger projects more clearly to outsource some things in several files and to write "classes", but for the sake of simplicity we remain here with a Javascript file with simple functions.

.

1. addressing the HTML 5 canvas element

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


We access the canvas element using the getElementById function and the id "canvas" assigned above. Then we create a 2D context in which we will draw our graphics later.

2. add necessary variables

var backgroundImg = new Image();
var enemyImg = new Image();

var character = null;
var fireball = null;

var enemies = {};
var keysDown = {};

var frametimeBefore = Date.now();
var level = 0;

We don't need more than that. We have two image objects, one for the background and one for the enemy graphics. Then we have a character obekt and the fireball object which the character can fire. The enemies we add to the level later will all come into the enemies array and the keyboard input into the keysDown array. Why we put the keystrokes into an array will be explained later. Finally, we have a variable that we need for the calculation of the frame time and a level variable in which we store the current level.

3. load the graphics and create the essential objects

function init()
{
    character = { img: new Image(), posX: 200, posY: 200, shooting: false, hp: 1000, speed: 300 };
    shot = { img: new Image(), posX: 0, posY: 0, dirX: 0, dirY: 0, speed: 600 };
    
    backgroundImg.src = 'images/background.png';
    character.img.src = 'images/character.png';
    shot.img.src = 'images/shot.png';
    enemyImg.src = 'images/enemy.png';
}

We create the character object and the fireball, each consisting of an image object, the position and the motion speed in px/s. In the character object we also store the status, if a fireball is currently active and the life points of the character. In the fireball object we also save the direction in which it moves. Then we load all the graphics by setting the src element of the image objects.

4. drawing of graphics and text

function draw()
{
    ctx.drawImage(backgroundImg, 0, 0);
    
    if(character.hp > 0)
    {
        for(var i = 0; i < enemies.length; ++i)
        {
            ctx.drawImage(enemies[i].img, enemies[i].posX, enemies[i].posY);
        }

        ctx.drawImage(character.img, character.posX, character.posY);

        if(character.shooting)
        {
            ctx.drawImage(shot.img, shot.posX, shot.posY);
        }
    }
    
    ctx.font = "20px Verdana";
    ctx.fillStyle = 'white';
    ctx.fillText("Level: " + level, 20, 30)
    ctx.fillText("HP: " + Math.ceil(character.hp), 20, 60);
}

As we have loaded all graphics and created all objects, we can already draw them. In the first line we draw the background at the position (0, 0). Then we draw all enemies, the character and the fireball (if it is active, i.e. fired). Opponents, character and fireball are only drawn if the character has more than 0 life points, i.e. is still alive. Then we draw two more texts, one that shows us the level and one that shows us the rounded up life points of the character. Why it is rounded here will become apparent later.

5. The game loop

Vielleicht auch interessant
Gether - Final (Full Code)
Gether - Final (Full Code)

Gether - Kooperatives Multiplayer Game - Full Code

In order to really draw and something happens, we have to call the created functions. The init function should only be called once, while the draw function should be called as often as possible. Therefore we create a function that serves as a game loop, where the frametime calculation and the logic of the game will be added later on.

function gameLoop()
{
    draw();
}

init();
setInterval(gameLoop, 0);

We create the function gameLoop and call it with setInterval without delay (the 0 stands for 0 milliseconds pause until the next call of gameLoop). Before that we call the previously created init function which loads the graphics, creates objects, etc. The current game.js now looks as follows:

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

var backgroundImg = new Image();
var enemyImg = new Image();

var character = null;
var fireball = null;

var enemies = {};
var keysDown = {};

var frametimeBefore = Date.now();
var level = 0;

function init()
{
    character = { img: new Image(), posX: 200, posY: 200, shooting: false, hp: 1000, speed: 300 };
    shot = { img: new Image(), posX: 0, posY: 0, dirX: 0, dirY: 0, speed: 600 };
    
    backgroundImg.src = 'images/background.png';
    character.img.src = 'images/character.png';
    shot.img.src = 'images/shot.png';
    enemyImg.src = 'images/enemy.png';
}

function draw()
{
    ctx.drawImage(backgroundImg, 0, 0);
    
    if(character.hp > 0)
    {
        for(var i = 0; i < enemies.length; ++i)
        {
            ctx.drawImage(enemies[i].img, enemies[i].posX, enemies[i].posY);
        }

        ctx.drawImage(character.img, character.posX, character.posY);

        if(character.shooting)
        {
            ctx.drawImage(shot.img, shot.posX, shot.posY);
        }
    }
    
    ctx.font = "20px Verdana";
    ctx.fillStyle = 'white';
    ctx.fillText("Level: " + level, 20, 30)
    ctx.fillText("HP: " + Math.ceil(character.hp), 20, 60);
}

function gameLoop()
{
    draw();
}

init();
setInterval(gameLoop, 0);

And the current result should look like this: screen2.png

Since this might be a bit much at once, I have divided this article into two. In the second part we take care of the most important thing, the game mechanics.

Next site
Final
Leave a like or comment (~‾▿‾)~
Name Text