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!

















