Today I would like to show you how to make a very basic isometric game map. It’s not really optimized and there are still plenty of things to do. But well, it’s a good start I think.
1. Introduction
First… I will assume you’re using jQuery, because I do and I used it to write the isometric map. After this article you will have a fully working jQuery plugin that can create a isometric map out of a array and some other options. The styling is completly done by a small stylesheet and spritesheet. You can easily enhance it and also make use of the very basic objects that can be added.
Also the array that you give to the plugin doesn’t need to start with “array[0][0]” so you can easily load content with ajax from the current location. This might be useful because you could have a array beginning with 2545 as y value or something like this.

This image displays how coordinates are arranged on the game map. on the left corner there is the lowest value, in our case there is 0,0. The x-value gets enhanced to the bottom right and the y-values enhance to the top right.
2. Features
- Easy styleable
- Easy to enhance
- Automatic focus on specific coordinates
- Basic object support
- Spritesheet
- As many different tiles as you want
- Fits into every div
- jQuery Plugin
- Dynamic TileSizes
- Create as many isometric maps as you want
3. Infos
I used the following free spritesheet by http://www.opengameart.org
On the html side you only need an unique element with a fixed width and height. And of course you need to include the javascript files and initiate the plugin. But I think this is self-explaining.
The plugin we will write will be called like this: $(element).gameMap({OPTIONS}); For example like this:
$('div#map').gameMap({map:mapdata,xpos:24,ypos:38,tilesize:128});
The map data needs to be a multidimensional array / object like this:
map[y][x]['tile'] and map[y][x]['object']
4. jQuery Plugin
First the javascript file, I commented every line to explain how it works. If this is not enough for you, just shout and I will add some more explanation of it.
/*! * jQuery Isometric Map Plugin * http://www.cw-internetdienste.de/ * * Copyright 2010, Christian Weber * Free for commercial and * non-commercial use. Please shoot * me an email if you use it. Would love * to see it in action.* * Date: Wed May 5 17:12:43 2010 +0100 */ // enables the $ function even if its disabled because of jQuery compatibility mode (function($) { // create gameMap namespace / main function // so it can be used using $(element).gameMap(); $.fn.gameMap = function(options) { // public property access // those set the base values $.fn.gameMap.defaults = { xpos : 50, ypos : 50, mapsize:100, tilesize:64, xcorrection:30, ycorrection:15, bgcolor:'#000000', map : {} }; // create the configuration file // this merges the defaults properties with the given options // the bool value at the beginning lets the function check recusively var config = $.extend(true,$.fn.gameMap.defaults,options); // get the elements height and width // self explaining var wWidth = $(this).width(); var wHeight = $(this).height(); // sets the baseline for rendering of the isometric tiles // as they go diagonal, we have to begin in the middle var half = (config.mapsize*(config.tilesize/2))/2; // just to be on the secure size we overload the variable to a local one // so we have access to it for every instance and not globally var obj = $(this); // create base function // this is the constructor function that gets // called at the end of this plugin $.fn.gameMap.init_game_interface = function() { // set the first game map properties // fill the backgorund with a base color // isometric maps wont be filling at the corners obj.css('background-color',config.bgcolor); // check if the content container is existing // if not add it to the given div. this is needed // for easy displaying of the correct part of the map // if it is bigger than the elements size if(obj.children('div.content').length == 0) { obj.append('</pre> <pre class="javascript">'); } // paint the map // initialize the map rendering obj.gameMap.initMap(); } // map rendering function $.fn.gameMap.initMap = function() { // set the size of the content element so nothing gets lost
// the height gets only multiplicated with half of the tiles size // as they are positioned differently and only half of the tiles size // matters. else we would have free sapce between the tiles obj.children('div.content').css('width',(config.mapsize*config.tilesize)+'px').css('height',(config.map[0].length*(config.tilesize/2))+'px'); // create the isomap // loops through the whole map data array // no matter where it starts for(var y in config.map) { for(var x in config.map[y]) { // call the intern function to create a new tile // can also be used to add new tiles after the // plugin got initialized obj.gameMap.addTile(config.map[y][x],x,y); } } // move to the starting position // this will center on the given coordinates obj.gameMap.moveMap(config.xpos,config.ypos); } // tile adding function $.fn.gameMap.addTile = function(tile,x,y) { // calculate x and y position of the tile // sometimes the images have not totally correct dimensions like in our case // so we have to use x and y corrections to position everything correctly // for the xposition of the tile we just have to sum the x and y position // as for example 1,0 and 0,1 will have the same x-position var xpos = config.tilesize+((x*config.xcorrection)+((y)*config.xcorrection)); // the y position is a bit more complicated. we have to remember that sometimes // it has to go up and sometimes down from the baseline, we calculated at the // beginning. so we just subtract the calculation of the y value minus the x value // if a positive value will be subtracted from the baseline it will be an addition // as + and - results in - so the tile will be higher than the baseline. // on a negative value - - it will result in a positive value so the position of // the tile will be lower than the baseline var ypos = half-(((y)*config.ycorrection)-(x*config.ycorrection)); // check if this is the starting position and mark it // this was just for testing purposes so we can see // the given starting position visually var hilight = ''; if(x==config.xpos && y == config.ypos) { hilight = 'border:1px solid #990000;'; } // create element // we create a div element with the correct tile class and the calculated x and y // positions as top and left values of the inline css // this also calculated the correct z-index as bottom left elements will aways // needa higher priority than the tiles behind them. var el = '</pre> <pre class="javascript">'; // add to content element // just adds the element to the content element $(el).appendTo(obj.children('div.content')); // attach information event // this was also added for testing purposes but might be useful obj.gameMap.tileInfo($('div#'+obj.attr('id')+'_tile_'+x+'_'+y),x,y); } // the information event i created for testing purposes $.fn.gameMap.tileInfo = function(tile,x,y) { // on mouse over it shows some details of the tile including its position // and the top and left values tile.mouseover(function() { $('div#interface p').html(typeof(tile)+' ('+tile.attr('id')+') on '+x+','+y+' Pos: '+tile.css('left')+'px, '+tile.css('top')+'px'); }); } // this function centers the map on a given position $.fn.gameMap.moveMap = function(x,y) { // set the correct position of the object // the calculations are the same as the ones of each tile // except that we subtract the half of the elements height // and width to have the coordinate at the middle obj.scrollLeft((config.tilesize+((x*config.xcorrection)+((y)*config.xcorrection)))-(wWidth/2)).scrollTop((half-(((y)*config.ycorrection)-(x*config.ycorrection)))-(wHeight/2)); } // call the constructor function $.fn.gameMap.init_game_interface(); // return the jQuery object as every jQuery function does // enables something like this $(element).gameMap().css('border','5px solid #990000'); return obj; }; })(jQuery);
5. Stylesheet
Now the stylesheet. I assume you know how to use spritesheets:
html, body { margin:0px; padding:0px; color:#333333; }
div#map {
width:600px;
height:400px;
margin:0px auto;
border:4px solid #CCCCCC;
background-color:#000000;
z-index:0;
overflow: hidden;
}
div#map2 {
width: 800px;
height:250px;
border:5px solid #990000;
margin:10px auto;
overflow: hidden;
}
div.content {
position: relative;
overflow: hidden;
}
div.content div.tile {
width:64px;
position: absolute;
height:64px;
line-height:64px;
background-image:url('grass_and_water.png');
}
div.content div.tile:hover { opacity:0.8; -moz-opacity:0.8; -webkit-opacity:0.8; -khtml-opacity:0.8; }
.grass_0 { background-position:0px 0px; }
.grass_1 { background-position:64px 0px; }
.grass_2 { background-position:128px 0px; }
.grass_3 { background-position:192px 0px; }
.grass_4 { background-position:0px 58px; }
.grass_5 { background-position:64px 58px; }
.grass_6 { background-position:128px 58px;}
.grass_7 { background-position:192px 58px; }
div#map div#content div.tile div.object {}
.npc_0 { background:transparent url('temple.png') top left no-repeat; position:relative;width:256px; height:128px;left:-128px;bottom:96px; }
6. Final Words
Thanks for your time. I hope you like it, even that it is very simple and basic. But it should give you a good start for your own isometric map. Especially objects and tiles / objects selection should be taken care of. This can be done with a mouseover check to see if the mouse is above a transparent pixel or not. As JavaScript doesn’t have functionality to do this itself, you could use canvas to generate some kind of transparency-arrays.
Best Regards,
Chris

12 comments
WP Themes / 1085 Tagen
Amiable fill someone in on and this post helped me alot in my college assignement. Thanks you on your information.
WP Themes / 1059 Tagen
Good brief and this fill someone in on helped me alot in my college assignement. Say thank you you on your information.
Emil / 1056 Tagen
Thanks. But when I copy your sample to my site, it’s pitch black and no hover recognization etc, what could be wrong?
Christian Weber / 1032 Tagen
Hm weird, can you give me a link?
Rob Evans / 982 Tagen
You may also be interested in the Isogenic Engine. It is designed for isometric games and uses canvas to output. There are many example videos available on youtube showing the developmental stages of the engine.
It’s not ready for release yet but you can register your interest and the site has some developer blog entries that might be interesting to people writing an isometric game.
BioHazard / 890 Tagen
hm…
the only actual manual in the web about isometric maps is yours…
i have to write it without jquery…
just it made me sure that its possible to make continious game map like google earth…
Facundo / 817 Tagen
Hi Christian!
I was observing that there is not much movement in hydra games and I’m interested in talking some things about the site with you.
Please, if you see this mail contact me soon.
Greetings.
Facundo.
James Synge / 575 Tagen
Thanks very much for sharing your work.
I noticed that the tiles weren’t quite aligned correctly (typically a few vertical pixels). The problem appeared to be with the CSS styles, and then the javascript code was modified to try to compensate, but only incompletely.
I’ve posted a page with a script that generates a random map here, hopefully showing correct alignment of the tiles (I didn’t use the support for objects above the tiles).
http://dmcpanthers.appspot.com/home/jamessynge/isomap/my-iso-map-2.html
Christian Weber / 575 Tagen
Looks really good! Your randomly generated map looks a lot better than mine, but well wasn’t intended to look that good
However you’re right. With some corrections of the CSS the x / y corrections of the JavaScript could get removed. Especially with CSS3 you could even handle the transformation of tiles, so you can just use normal images instead of already rotated ones. Will try to come up with something new.
Thanks so much for your input.
James Synge / 574 Tagen
When I submitted my earlier comment, the UI seemed to hang for a very long time, so I thought the comment was lost. As a result, I posted a note on my blog, with a cleaned up version of the map here:
http://jsdabbler.appspot.com/home/jamessynge/isomap/random-isomap.html
Ali / 154 Tagen
I’ve copied your code but the whole div will be blakish
Christian Weber / 152 Tagen
Mhm weird, do you have a link where I can look over it?