[Tutorial] Part 4 : How to create a HTML5 game using Tiled Map Editor, JS and Canvas

in #gamedev7 years ago (edited)

This is a continuation from the previous post ...

Part 4: HTML5 Canvas and Javascript

Doge Warrior Screenshot01.png

Today i m going to show you how to use HTML5 canvas and Javascript to render images and animations. Let's open any text editor of your choice and start writing some Javascript.

We are going to need 2 files :

  1. index.html
  2. dogewarrior.js

Using HTML5 Canvas

In your html file, we only need to source our javascript file and a simple canvas tag as such:

index.html:

<script src="dogewarrior.js"></script>
<canvas id="cv"></canvas>

You can add other HTML and CSS styling later. For now, we only need a canvas.

Now let's create some basic code structure in our javascript file.

dogewarrior.js:

function DogeWarrior() {
    this.init = function() {
    
    }   
}

document.addEventListener("DOMContentLoaded", function() {
    var dw = new DogeWarrior();
    dw.init();
});

Basically what this does is that when the Document is loaded, an object of DogeWarrior will be instantiated and the instance will invoke its init method. We ll add more methods as we progress along.

To paint picture on the Canvas, we ll need to use the canvas's context and some basic draw calls..

Let's add the following into our init method

this.canvas = document.getElementById("cv");
this.canvas.style.backgroundColor = "#000000";
this.canvas.width  = 1200 ;
this.canvas.height = 800 ;
this.ctxt = this.canvas.getContext('2d');

We ll adjust the canvas width and height based on window size later. For now, just fix it to 1200 x 800.

Now we can use this.ctxt to paint sprites into the canvas. But before that, we first need to load the images.

Loading Resources

We can use the src() method of Image object to load the sprite sheet, however, we need to ensure that all the required images have already been loaded before we can start running our game loop. To do this, we ll add event listeners for our loading processes.

We can display a simple text showing % of resources loaded by painting text onto the canvas.

function DogeWarrior() {

    this.init = function() {
    
        this.canvas = document.getElementById("cv");
        this.canvas.style.backgroundColor = "#222222";
        this.canvas.width  = 1200 ;
        this.canvas.height = 800 ;
        this.ctxt = this.canvas.getContext('2d');
        this.resource_loaded = 0;
        this.total_resource = 2;
        this.load_resources();
    }


    
    this.load_resources = function(){
        var dw = this;  
        this.sprite_mainchar_body = new Image();
        this.sprite_mainchar_body.src = 'images/dogewarrior_body.png';
        this.sprite_mainchar_body.addEventListener('load', function() {
            dw.on_load_completed();
        }, false);

        this.sprite_mainchar_head = new Image();
        this.sprite_mainchar_head.src = "images/dogewarrior_head.png";
        this.sprite_mainchar_head.addEventListener('load', function() {
            dw.on_load_completed();
        }, false);
    }

    this.on_load_completed = function() {

        var dw = this;
        this.resource_loaded += 1;
        this.update_loading_screen();
        
        if ( this.resource_loaded == this.total_resource ) {
            console.log("Loading Completed");
        } 
    }


    this.update_loading_screen = function() {

        var percent_complete = ( this.resource_loaded * 100.0 / this.total_resource).toFixed(2);
        this.ctxt.clearRect( 0,0, this.canvas.width , this.canvas.height );
        this.ctxt.fillStyle = "white";
        this.ctxt.font = "14px Comic Sans MS";
        var msg = "Loading Resources . " + percent_complete + "% loaded";
        this.ctxt.fillText( msg , this.canvas.width / 2 - msg.length * 6 / 2 , this.canvas.height /2 );
    }
}

Test-Running with Mongoose Simple Web Server.

To test run the game, you can download a simple web server(168kb) here .

mongooese_logo

Just put the executable in your directory, double click it and the web server will serve the content from the current directory.

Open your browser and go to url http://localhost:8080/index.html to view your page.

My directory structure looks something like this:

index.html
dogewarrior.js
images
    |_ dogewarrior_head.png
    |_ dogewarrior_body.png

Creating a simple Game Loop

A game loop runs continuously during gameplay. Each turn of the loop, it processes user input without blocking, updates the game state, and renders the game. It tracks the passage of time to control the rate of gameplay.


src: gameprogrammingpatterns.com

There are 2 ways you can create a game loop. You can use SetTimeout/SetInterval or you can use requestAnimationFrame

The advantages of using requestAnimationFrame over setTimeout is explained here , so we'll use requestAnimationFrame

First, we are going to create on_timer function as such

this.on_timer = function() {

    // Update 
    // this.on_update();

    // Draw
    this.on_draw();

    var dw = this;
    window.requestAnimationFrame( function() {
        dw.on_timer();
    });
}

also, add dw.on_timer() after loading completed in on_load_completed

this.on_load_completed = function() {

    var dw = this;
    this.resource_loaded += 1;
    this.update_loading_screen();
    
    if ( this.resource_loaded == this.total_resource ) {
        console.log("Loading Completed");
        dw.on_timer();
        
    } 
}

Render Game State into Canvas

We are going to create our on_draw() method first that gets called n times every second.

this.on_draw = function() {
    
    // Clear the canvas
    this.ctxt.clearRect( 0,0, this.canvas.width , this.canvas.height );

    // Draw Main Characters
    this.ctxt.drawImage( this.sprite_mainchar_body , 
                                this.player.width  * this.player.framex , 
                                this.player.height * this.player.framey , 
                                this.player.width , 
                                this.player.height , 
                           this.player.x - this.camera.x, 
                           this.player.y - this.camera.y, 
                           this.player.width , 
                           this.player.height );
    
    this.ctxt.drawImage( this.sprite_mainchar_head , 
                                this.player.width_head * this.player.framex_head,
                                this.player.height_head * this.player.framey_head,
                                this.player.width_head,
                                this.player.height_head,
                            this.player.x - this.camera.x + this.player.head_offsetx ,
                            this.player.y - this.camera.y + this.player.head_offsety ,
                            this.player.width_head,
                            this.player.height_head,
                            );
}

We'll also need a player object and a camera object. We'll use simple hash object {} for this purpose. In your on_init, add the following:

    this.player = {};
    this.player.x       = 0;
    this.player.y       = 0;
    this.player.width   = 120;
    this.player.height  = 120;
    this.player.framex  = 0;
    this.player.framey  = 0;
    this.player.width_head = 40;
    this.player.height_head = 40;
    this.player.framex_head = 0;
    this.player.framey_head = 0;
    this.player.head_offsetx = 39;
    this.player.head_offsety = 17;
    
    this.camera = {};
    this.camera.x = 0;
    this.camera.y = 0;

ok, by now, when you view your index.html, you should get something that looks like this:

wip

Alright, that's all for today, we'll continue with putting background, adding controls and more in the next episode

To be Continued ...

Sort:  

Seems easy enough to create a simple game using Tiled Map Editor, JS and Canvas. I never played with Canvas. :)

The Web has come a long way.

This is such a great article! Thank you for sharing this. I'd love to learn coding and try my hand at a simple video game. I'm gonna follow along to get a glympse into it. At the moment I'm focusing on character and story, making my own comic. I'll be exploring video games more once I'm done with this project. ;-)

this is impressive. thanks @tensaix2j for sharing

thank you so much for this great informative post:)
Upvoted & Followed

jajaj is funny the face