First off the reason this tutorial is referred to as diamond isometric is because we will be wrapping up on the simpler isometric method soon. This tutorial is split into two parts. Part one covers the simple scrolling and displaying only a visible area of the map. The second tidies up the offsets we have added as well as implementing a further method to keep our drawing minimal and overall speeding up our game.
What is this diamond method you speak of you ask?
It’s basically what we have been using so far. If you look at your isometric map it is a diamond. It is by far the simplest method of drawing out your tiles as well as keeping track of player positions, interactions and other such game requirements like path finding. The tutorial after this written up by Ed will cover the path finding and AI basics for this sort of isometric map. This tutorial will cover producing a large scrolling isometric map and some optimization techniques to help speed things up in canvas.
What we aim to have at the end of this is a large smooth scrolling 100×100 tile map which only draws the most required tiles. We will have a startX and startY range which when calculated will be the starting point in the array for our draw function. This alone would reduce the above screenshot like so:
With only the tile rows being drawn that are needed to fill the screen we have already reduced our 10,000 tiled map to 49 tiles at a time. If this is for multiple layers then that is a huge saving. On top of this we can use a second tile limiting method which I found also contributes to keeping that frame rate high meaning Ralph can avoid those possessed water coolers worry free.
Using startX and startY within our array we can work out easily what the middle tile is on screen. With a couple of small conditional checks you can check the distance of the surrounding tiles and make sure they are worth drawing. For example in the above screenshot, due to our diamond system we have the point unseen tiles on all four sides still being drawn. The outcome would look like this:
Taking the total drawn tiles from 49 down to 28.
So we’ll just dive straight in and fire out our scrolling.
Just following on from tutorial 7: http://glacialflame.com/tutorials/tiles/06/
First change to make if you are still using a small viewport is to increase its width and height to a decent size. Perhaps even centre it. (make sure you update the clearRect to match your new sizes e.g. ctx.clearRect(0,0,500,500).
Using the following little script I had a random array of 100×100 tiles made up:
http://glacialflame.com/tutorials/tiles/07/gen.php?x=100&y=100&type=array
The array it generates is just made up of 0s and 1s.
If you replace the current contents of both the map and objectMap with a random generate array as well.
If you declare at the top with the rest of your global variables:
var mapXD; var mapYD;
These two variables will hold the direction we are scrolling.
In the mouseCheck(e) function add the following anywhere under where x and y are set. As the width I’m using is 500, I set it to have a 100 space
if(x - canvas.offsetLeft> 400 ){
mapXD= 1;
}else if(x -canvas.offsetLeft < 100){
mapXD =2;
}else{
mapXD = 0;
}
if(y - canvas.offsetTop > 400){
mapYD= 2;
}else if(y - canvas.offsetTop < 100){
mapYD =1;
}else{
mapYD = 0;
}
In the drawMap() function add the following before the draw loops:
if(mapXD == 1){mapX -= 5;}
if(mapXD == 2){mapX += 5;}
if(mapYD == 1){mapY += 5;}
if(mapYD == 2){mapY -= 5;}
And that’s all that is required for the scrolling part. Using the mouse we can now move around our large world as we please. The first issue here is we have 10,000 tiles being drawn at the same time, and although it may or may not run smooth depending on your pc specs there is some demanding improvements to be made.
Add the following to the drawMap after the previous addition of code:
startY= mapY+(mapX/2);
startX=(startY-mapX);
startY=Math.round(-startY/25);
startX=Math.round(-startX/25);
if(startX < 0){startX = 0}
if(startY < 0){startY = 0 }
And update your two tile drawing for loops to reflect the following:
for(i=startX;i<map.length;i++){
for(j=startY;j<map[i].length;j++){
The startX and startY defines where to start within the map array from position of your map according to its mapX and mapY values.
If you test your code now you will see that you always have a pointing tip to your map.
Next up we will add a range of tiles to draw.
Declare another two variables within the drawMap()
var rangeY = 10; var rangeX = 10;
Then add the following before draw your for loops once again
if(startY+rangeY > map.length){ rangeY = map.length-startY;}
if(startX+rangeX > map.length){ rangeX = map.length-startX;}
Finally update your loops to take in the range.
for(i=startX;i<startX+rangeX;i++){
for(j=startY;j<startY+rangeY;j++){
rangeX and rangeY represent how many tiles you wish to draw. If you run your code you will see it should scroll properly but may need some adjustments. If your finding your map keeps running away then the following will need updated:
var xpos = (i-j)*tileH+ mapX; var ypos = (i+j)*tileH/2+ mapY;
In my case my mapX needed reversed with a further offset applied:
var xpos = (i-j)*tileH - mapX + 235; var ypos = (i+j)*tileH/2+ mapY+50;
These offsets and ranges will all need customized to your specific tiles and how much you wish to draw. With the right offset and tile range you can fill your screen no bother and keep drawing to a minimum.
var mapX = 0; var mapY = 0;
For the purpose of this part of the tutorial I set the initial mapX and mapY globals to zero.
The next part of the tutorial will cover fixing the mouse for your new offsets and adjusting the range to fill your viewport as well as the second distance from centre tile speed-up method. Will have the next part of this up in a couple of days, probably Monday.
As always the full source code so far can be seen here:
http://glacialflame.com/tutorials/tiles/07/
Let me know if you run into any issues!







Very well done!
Also, the links to any of the examples are not working!
Cheers Niels,
Fixed the links as well!
Nice tutorial ever!
Thanks Iain!
Thanks for the kind words Zojai.
Nicely done! Also good tutorial too. Just exactly what I needed.
But somehow, when the cursor is out of the canvas area, the viewport/scrolling– am I saying it right? I’m not majoring in cg or game programming –is going mad.
Btw, I’ve already read your prev post about generating isometric map. I found there’s a slightly different between this iso map and the previous one, that’s the tiles are not treated as an img tag, how you done this? Thank you very much.
tested on: Chrome 11, IE 9 (not working-blank), Firefox 4.
Hi Dkartono,
Sorry for a late reply (8 months really isn’t good). Did you manage to get on ok and move on? If not feel free to drop a link here and I’ll take a look.
Thanks for the feedback,
Iain
Hello, one thing that doesnt work is the mouse, I am using google chrome and I decided to copy the code from a earlier tutorial. The mouseCheck function is the same though and I found it had quite a large offset. After mucking around with the code and some guess work the code that works for me is as follows:
ymouse=((y-mapY)-(x/2))+(mapY/2);
xmouse=(x+ymouse-25)+(mapX);
this gives me an accurate x and y position. I wound like to hear your opinion on this issue.
Just found out that doesnt work either so ill have to keep trying
actually i think your code works the only problem was it was going backwards so thme offsets were going in the wrong direction anyway i had to change the rendering to
var xpos = (i-j)*tileH + mapX;
var ypos = (i+j)*tileH/2 + mapY;
I feel so stupid now
as i read the bottom of the article, sorry
Glad you managed to get it fixed Ryan, I’ll hopefully have a bit more time to dedicate to this for the next couple of months so should have a way faster response should you run into any issues.
Great !
I look forward to future tutorials !
Thanks Y
I wanna see more tutorials here… Like zoom and more…
I’ll get the next part out for optimizing the map drawing with a little trick that can help and maybe cover something like rotate after?
With 5/6 months doing HTML5 for companies I’ve picked up a lot more and have some pretty good aspects for doing things alternatively that I could cover as well e.g. preloaders, loading mass images easier and so on.
Best,
Iain
Hi there nice tutorial found a bug
.
Change on line 75:
mapXD= 1; to mapXD= 2;
and on line 77:
mapXD= 2; to mapXD= 1;
Thanks Frank
Cheers Frank.
This is the best tutorial I’ve seen on the subject of isometric games in JavaScript. Thank you for writing it, got me started really well.
Do you ever plan on writing more? This seems to be over half a year old.
I’d be very interested in subjects like saving levels efficiently, procedural generation of levels, height variation, making the code more dynamic/object-oriented and possibility and reasons of porting this to use WebGL instead of canvas when possible.
Heck, I’d pay you to get tutorials for stuff like that.
If there’s no plans for any of the subjects above, could you point me to other resources? Some very fancy engines like Isogenic Engine start popping up, but there’s little to no information on how to build even basic engines.
Again, thanks for the great work. This has been extremely valuable tutorial for me.
Thanks for the wonderful comment Steve,
How are you getting on, did you find resources for what you where after? I’m sorry there was such a long period between updates (work and university).
If I get time later during this week (Thursday hopefully) and no clients are chasing me I’ll sit down and write up the next part to this tutorial if it still appeals?
Thanks again for your appreciation!
Iain
Thanks for the tutorial! I guess you didnt get to finish the follow up on this one
Any tips on fixing the mouse overlay? Currently with the scrolling its nowhere near the cursor.
Would like to point and click to add stuff to the map.
Hi Andy,
I’ll hopefully get time later this week to write up more if you’re still interested. I’m guessing by now there is a lot more HTML5 tutorial sites that quite possibly beat my tutorials now.
Thanks for your feedback though, always great to have the tutorials appreciated!
Very instructing tutorial !
part 2 coming soon ?
Hopefully soon seb, sorry for the delay!
Thanks a lot for this, really looking forward to the next one
I have to say, great tutorial so far! I’m hoping the next part is coming soon. Here is my game so far, just thought you may like to see it. There are a few differences from your tutorial, mainly the viewport sticks to the player so there is no need for scrolling. I have no idea on how to do enemy pathing and attacking so I’m hoping you do some tutorials on those.
Thanks for making these great tuts!
Hi James, I’ll hopefully be picking up the tutorials again soon enough!