Starting an HTML 5 Tile Based Canvas Game – Game Area and Character
One of the most common games people want to make game wise is a tile based RPG. To start you need to add a character to the canvas and be able to move him around with your keyboard that is the primary goal of this article.
To see this working visit the github page. Also you can view all of the code in the github repository.
Getting Started
So to actually get something going we need to start with some basics that allow for everything to work and for future development. Here is what we are going to need:
- Main Page
- Game Area (canvas)
- Game Loop
- Character
- Keyboard Code
- Game Engine Execution
Main Page
The main page is easy to do because it is just some basic html.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/helper.js"></script>
<script src="js/character.js"></script>
<script src="js/game.js"></script>
<script src="js/main.js"></script>
</head>
<body>
<canvas id="gamearea" width="480px" height="320px"></canvas>
</body>
</html>
The code above is fairly self explanatory so I won’t bore you explaining it (take note of canvas element). However, here is a list of the JavaScript files and their use:
- helper.js – for the key presses
- character.js – your main object code for the main character of the game
- game.js – essentially the game engine
- main.js – the execution of the the rest of the game.
Game Area (Canvas)
var Game = {};
Game.fps = 30;
Game.initialize = function() {
this.entities = [];
this.context = document.getElementById("gamearea").getContext("2d");
};
This sets up our Game object and constructor. The constructor gets the canvas 2d context for us to use in the rest of the engine. The canvas context is where we do all of our work. When we move, rotate, or draw stuff on the screen it all takes place through the canvas context.
We also have an entities array to reference all of our assets that we display in the game. This is a good solution for now since we won’t have that many entities to display. Keep it light is the best solution, for this example.
Game.draw = function(){
this.context.clearRect(0,0,480,320);
for(var i = 0; i < this.entities.length; i++){
this.entities[i].draw(this.context);
}
};
This is our draw function where we will draw out all of our entities on to our canvas, and this draw function will be called from our game loop which we will hit on later.
First, it clears the canvas of everything and then redraws all of the entities. This is done to consistently draw stuff as things move across the screen or change.
Next we loop through all of our entities and call the draw function which will actually do the drawing of each entity.
Game.update = function(){
this.entities[0].update(this.context);
};
This update method is what we will use to call updates on everything in the game. For now we are just updating the first entity since we are only planning to have one. It just calls the update method of the entity, and it is up to the entity to know what to do from there.
Game.addPlayer = function(x, y){
Game.entities.push(new Character(x, y));
};
This is a very dumbed down way to add characters to the game, but it works for our purposes. Since entities are in an array we are simply pushing a new instantiated object on to the top of the array for our game engine to run.
Game Loop
Here is the code for the game loop itself. I wont explain it, but instead link you to the article I got it from which has a better explanation than I can give. Definitely give it a read since it explains a few things specific to doing a game loop in JavaScript.
Game.run = (function(){
var loops = 0, skipTicks = 1000 / Game.fps,
maxFrameSkip = 10,
nextGameTick = (new Date).getTime();
return function() {
loops = 0;
while ((new Date).getTime() > nextGameTick && loops < maxFrameSkip) {
Game.update();
nextGameTick += skipTicks;
loops++;
}
Game.draw();
};
})();
Character
Next up is character.js where we have all the code for our main character; creation, drawing, and movement.
function Character(x, y){
this.x = x;
this.y = y;
this.dude = new Image();
this.dude.src = "images/person.png";
}
This is setting up our Character object and the constructor. The constructor is setting the current location and instantiating new Image object for use in displaying our character, along with setting the location of the image. We will use all of this in our draw function, and the coordinates in our update function.
Character.prototype.draw = function(context){
if(this.dude.complete){
context.drawImage(this.dude, this.x, this.y);
};
};
All of our entities that will be displayed on the canvas will have a draw function associated with them, and will be called from the game engines draw function. In the case of our function here we check if the image has completed being loaded onto the screen, and if it has then we draw it onto the canvas. It is important to note that we should only draw the image onto the canvas after it has loaded, and that is what the complete property checks.
Character.prototype.update = function(context){
if (Key.isDown(Key.UP)) this.moveUp();
if (Key.isDown(Key.LEFT)) this.moveLeft();
if (Key.isDown(Key.DOWN)) this.moveDown();
if (Key.isDown(Key.RIGHT)) this.moveRight();
}
So far with our character the only thing we need to do when we update the character is move the character. So all we have to do is check for a keypress and call the proper function from there. We are calling a function from a helper which will be show here in a bit. The update for the character is where we check for the button press since the key press directly deals with character.
As you probably have noticed we are calling move methods from the current object. The following code is what we use for that. All it does is change the x,y coordinates by a bit each time you press the button.
Character.prototype.moveUp = function(){
this.y -= 2;
};
Character.prototype.moveDown = function(){
this.y += 2;
};
Character.prototype.moveLeft = function(){
this.x -= 2;
};
Character.prototype.moveRight = function(){
this.x += 2;
};
Keyboard Code
In the helper.js file we have our key press helper to make life easier when dealing with our keyboard, and events dealing with interaction with our game.
I got this code from this article Javascript Game Development – Keyboard Input. It is a great helper that helps take events and register actions. The numbers represent keys on the keyboard. In this case the arrow keys.
var Key = {
_pressed: {},
LEFT: 37,
UP: 38,
RIGHT: 39,
DOWN: 40,
isDown: function(keyCode){
return this._pressed[keyCode];
},
onKeydown: function(event){
this._pressed[event.keyCode] = true;
},
onKeyup: function(event){
delete this._pressed[event.keyCode];
}
};
window.addEventListener('keyup', function(event) { Key.onKeyup(event); }, false);
window.addEventListener('keydown', function(event) { Key.onKeydown(event); }, false);
Game Engine Execution
Finally, we are on to actually running our code and moving our character. We have already done all the hard work. All that is left is to now is to run the code.
window.onload = function(){
Game.initialize();
Game.addPlayer(30, 30);
Game._intervalId = setInterval(Game.run, 0);
};
This is very simple we initialize the game where we do our setup of our game pieces. Then we add our player to the game engine, and set our game to run continuously. That is it, all that is left now is to try it out.
Conclusion
The goal with this was to draw a character on the screen and move him around the playing area. It has been a fun adventure learning to do this, and a great dive into canvas without using a library of some sort. After writing all this code I noticed it is fairly simple, but learning it in the first place was kind of difficult. Canvas is big, convoluted, and not well documented on “how” to use it. If you want to get into canvas development be warned it is an uphill battle unless you use a library of some sort, and even then...