sometimes the images are not all loaded, here is how to fix it: just make a function and type the "for" loops in it and pass a parameter (context) in it and load it by the body with the onload function
first of really bad practice to hard code the 2D array in the same file as the renderer, containing the render data and rendering that data to the screen are two separete concerns. I would suggest using multiple rendering strategies for multiple different maps and recieve the 2D array from a rendering function, also, store the images in an array and use the number as an index rather than building up a lot of ifs and switches
You could make the code a lot cleaner if you put all the tiles inside a spritesheet. this would also make you do a lot less work since you wouldn't have to check if the tile is "sand" or "grass". Take a look at this for more info 😀 https://developer.mozilla.org/en-US/docs/Games/Techniques/Tilemaps
hi and thanks for your time. would hexagonal tiles work in a similar manor as this tutorial? i do understand that i would have to offset the rows and columns, i am just stuck on the syntax to draw images. html, css, javascript based project.
Sorry, I am kinda new to this, what does the second statement in the For loops do? I know, I know, the condition for the loop to be executed, by why would it be if i or j < maparray.length? What does that do?
This is a very good video, it teaches because we have been taught, we think because you teach of this.Thank you for yet another AWESOME and EDUCATIVE video.
you could use i and j instead of posX and posY, and multiply it with tile size. it should give you the same result. so your code will be: var tileSize = 32; context.drawImage( grass, ( i * tileSize ), ( j * tileSize ), tileSize, tileSize ); context.drawImage( sand, ( i * tileSize ), ( j * tileSize ), tileSize, tileSize ); 1st loop i = 0, 0 * 32 = 0 j = 0, 0 * 32 = 0 j = 1, 1 * 32 = 32 j = 2, 2 * 32 = 64 tileSize is defined before the loop hope it helps
I really like this technique because the matrix (multidimensional array) with simple integers gives you a nice visual analog for your rendered map. You can quickly gauge how the resulting map will look.
I know how to fix the bug that it doesnt draw the images: Well when the code loops through the for statement the images arent loaded yet. So what you could do is to set the for loop to when the images are loaded or in a loop. This is my code(It works! :D)
This is a really good tutorial but I would like to know how to do something just a tad bit more advanced. I have a grid of 16x72px and most of the images are supposed to take up more than one tile (most common size would be 1×4 tiles but there are several sizes). Is there a way to have one image span multiple tiles? At the moment, I am doing things the hard way with drawing the images directly to the canvas one instance at a time. I must warn you that I am very new to HTML5.
How does one go about detecting which tile say a character is on or nearby? Like if they were to walk on lava and take damage, or if they were to be running into a wall? Great tutorials by the way! Very informative and clear instructions.
29 responses to “Tutorial: Javascript Canvas Tutorial – draw a tile map for an RPG or Platformer in Javascript Game”
l fixed the bug that doesnt draw images without any onload functions.
sometimes the images are not all loaded, here is how to fix it: just make a function and type the "for" loops in it and pass a parameter (context) in it and load it by the body
with the onload function
first of really bad practice to hard code the 2D array in the same file as the renderer, containing the render data and rendering that data to the screen are two separete concerns. I would suggest using multiple rendering strategies for multiple different maps and recieve the 2D array from a rendering function, also, store the images in an array and use the number as an index rather than building up a lot of ifs and switches
Can request a copy of the code. Because in his video writing is not so clear please send a copy of his code via email taiey430@gmail.com I please help
You could make the code a lot cleaner if you put all the tiles inside a spritesheet. this would also make you do a lot less work since you wouldn't have to check if the tile is "sand" or "grass". Take a look at this for more info 😀 https://developer.mozilla.org/en-US/docs/Games/Techniques/Tilemaps
thank you so much this was really helpful
I don't talk to people who use Dreamweaver
Helped a lot!
This tutorial is the best thank you 🙂
hi and thanks for your time. would hexagonal tiles work in a similar manor as this tutorial? i do understand that i would have to offset the rows and columns, i am just stuck on the syntax to draw images. html, css, javascript based project.
Thank you so much!
I'm using Chrome to load it, I did a onload function.. but it still doesn't seem to work 🙁
Great Video! could you please do a tutorial on collisions of characters moving with keyboard input and colliding with map. tnx
Can you make tutorial how to scroll tiled map?
using comicsans lol
Sorry, I am kinda new to this, what does the second statement in the For loops do? I know, I know, the condition for the loop to be executed, by why would it be if i or j < maparray.length? What does that do?
Gracias brother por el aporte.
This is a very good video, it teaches because we have been taught, we think because you teach of this.Thank you for yet another AWESOME and EDUCATIVE video.
you could use i and j instead of posX and posY, and multiply it with tile size. it should give you the same result.
so your code will be:
var tileSize = 32;
context.drawImage( grass, ( i * tileSize ), ( j * tileSize ), tileSize, tileSize );
context.drawImage( sand, ( i * tileSize ), ( j * tileSize ), tileSize, tileSize );
1st loop
i = 0, 0 * 32 = 0
j = 0, 0 * 32 = 0
j = 1, 1 * 32 = 32
j = 2, 2 * 32 = 64
tileSize is defined before the loop
hope it helps
I really like this technique because the matrix (multidimensional array) with simple integers gives you a nice visual analog for your rendered map. You can quickly gauge how the resulting map will look.
I know how to fix the bug that it doesnt draw the images:
Well when the code loops through the for statement the images arent loaded yet.
So what you could do is to set the for loop to when the images are loaded or in a loop.
This is my code(It works! :D)
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Canvas Tile Map</title>
<style>
#canvas{
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="canvas" height="400px" width="500px"></canvas>
<script>
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var mapArray=[
[0,0,0,0,0,1,1,1,0,0],
[0,0,0,1,1,1,0,0,0,0],
[0,1,1,1,1,0,0,0,0,1],
[0,1,1,1,1,1,1,0,0,0],
[0,1,1,1,1,0,0,0,0,0]
];
var grass = new Image();
var stone = new Image();
grass.src= 'grass.png';
stone.src = 'stone.png';
var posX=0;
var posY = 0;
grass.onload = function (){
stone.onload = function (){
for(var i=0; i < mapArray.length; i++){
for(var j=0; j < mapArray[i].length; j++){
if(mapArray[i][j]==0){
context.drawImage(grass,posX, posY, 32, 32);
}
if(mapArray[i][j]==1){
context.drawImage(stone,posX,posY,32,32);
}
posX+=32;
}
posY+=32;
posX=0;
}
}
}
</script>
</body>
</html>
The canvas appears but i wont render the images:
<!doctype html>
<html>
<head>
<style>
#canvas {
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="canvas" height="400px" width="500px"></canvas>
<script>
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var mapArray=[
[1,1,1,1,1,1,1,1],
[1,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,1],
[1,1,1,1,1,1,1,1]
];
var grass = new Image();
var dirt = new Image();
var wall = new Image();
grass.src = 'grass.png';
dirt.src = 'dirt.png';
wall.src = 'wall.png';
var posX = 0;
var posY = 0;
for (var i=0; i < mapArray.length; i++){
for (var j=0; j < mapArray[i].length; j++){
if (mapArray[i][j] == 0){
context.drawImage(grass, posX, posY, 16, 16);
}
if (mapArray[i][j] == 1){
context.drawImage(wall, posX, posY, 16, 16);
}
posX += 16;
}
posX = 0;
posY +=16;
}
</script>
</body>
</html>
This is a really good tutorial but I would like to know how to do something just a tad bit more advanced. I have a grid of 16x72px and most of the images are supposed to take up more than one tile (most common size would be 1×4 tiles but there are several sizes). Is there a way to have one image span multiple tiles? At the moment, I am doing things the hard way with drawing the images directly to the canvas one instance at a time. I must warn you that I am very new to HTML5.
It creates a div, but it doesn't fill my images into it
This is working for me in FF but not GC? Any thoughts?
Really great. Thanks !
How does one go about detecting which tile say a character is on or nearby? Like if they were to walk on lava and take damage, or if they were to be running into a wall? Great tutorials by the way! Very informative and clear instructions.
This is good. I am looking for an example of a hex map.
How would I go about checking which tile my player is on ?