Creating a basic Isometric Map

Posted on 04.05.2015 20:59:41 in Browsergames, General, JavaScript, Webcoding 0 Comments

830d0566c92e0802831a099fa4d08210_grass_and_water-960

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.

Show Demo

The plugin we will write will be called like this: $(element).gameMap({OPTIONS}); For example like this:

1
$('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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/*!
 * jQuery Isometric Map Plugin
 *
 * 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. <img src="/web/20130831000853im_/http://www.cw-internetdienste.de/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley">
 *
 * 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 <img src="/web/20130831000853im_/http://www.cw-internetdienste.de/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley">
            // 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 &amp;&amp; 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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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

 

No comments yet

Post Comment

Everything? Send!

Spam Protection by WP-SpamFree