I'm currently writing a game that uses Isometric tiles to display a landscape on the screen. The landscape having hills and valleys is part of the game's design. After a search on the Internet for help in determining which tile I was on I was presented with the following options:
The first option is great if you have a flat landscape, but I'm not basing my game in Holland or any other area of flat land. The second option, which I've tried and it does work, has drawbacks in that I've got to blit the map twice onto two different back buffers, and on one of the back buffers I've got to blit in one colour per tile - very bad for performance. The final option at first seems good, but requires learning Direct 3D/DirectX Graphics.
I'll explain the theory behind my experiments and then I'll provide some sample code afterwards.
Experiment 1: One colour per tile
I first started with the second option and after a couple of days playing around had a simple program working that highlighted the correct tile. The following screen grab is the tile map that I used to see where on the map I was:
This map was generated initially and then updated every time I moved the screen around the map. This caused the system to lose a few frames/second as it had to draw the same map twice. I also had problems finding where the mouse was as this involved a lock, read and finally an unlock which took time. Since this operation was being performed every time the mouse/screen moved then it started to add up to being a very slow process.
Experiment 2: Adapting the mouse maps to be tile independent
I started to think about the possibilities of using Mouse maps after trying to get better performance out of the second option. Instead of using the normal isometric tile map:
I extended the shape to be a square and produced the following new standard iso mouse map for flat terrain
After a little bit of a play with the new mouse map system, I discovered that the original mouse map had to be used to find the tile, but the new tile would allow me to use all of my tiles as a base for their own mouse map. Thus the following tile set:
became the following mouse map templates:
At first glance this seems strange, especially tiles 4-7, 12-14 and the last 3 where the cyan colour is not a normal isometric flat tile, but this is okay and it works perfectly with the algorithms I'm using.
By using the first 4 steps in Ernest's book to get to the rough, yet flat tile position, I then allowed my system to enter a while loop to get to the final tile. The full steps in Ernest's book are:
It was this final step that I changed into a while loop, and using the following test map I tried a little test:
As can be seen in the simple map I was using, the game I'm working on can have cliffs. The purple area shows where a cliff would go. My mouse mapping algorithm was entering an infinite loop moving north east and south west whenever my mouse entered this purple area. This was not what you would want to happen in a real game. So I've got this problem to sort out, and at the moment I think the easiest way would be to limit the number of moves the system can make in opposite directions.
Explanation of how to use my method
The first 4 steps of Ernest's Mouse -> Tile conversion are unchanged, except I'm adding a quarter tile height to the fine Y position so that the fine co-ordinates are sitting inside of the normal mouse map inside of my extended mouse map. The final step (using the mouse map) has to be changed slightly.
In a normal mouse map lookup function you get the direction to travel and then exit after performing the movement. With my method you keep performing the lookup / movement loop until the lookup returns no movement, i.e. the colour is white.
Using the following image (this is my test map from before, but this time the red lines shows the coarse division of the map):
If you look at the mouse pointer (the enlarged view on the right) then you will notice that using a normal iso mouse map the tile returned would be 1,1, whereas the actual tile is 2,2. After getting the initial tile number (1,1) we now switch over to the extended mouse maps (the following images have been enlarged to aid in the explinations):
The tile at map position 1,1 is:
and the mouse map for this is :
If you overlay the mouse pointer onto the mouse map you get :
and as you can see the mouse is in the cyan area, and this means to move south by one tile, so we do this and get the following Tile 2,2 image :
and mouse map :
We also need to update the fine coordinates by a full tile's height : tile dimensions are 32 x 16 (64 x 32 for larger tile set) so fy has 16 (32) subtracted from it, and the new position of the mouse on the new mouse map is :
just inside of the white area of the tile. Thus we have found the tile we wanted, but not quite yet. Although this is the correct tile, the position of the mouse pointer is wrong, if you compare the two mouse maps you will notice that the mouse pointer on the first mouse map was about a quarter of a tile height down (this is the offset I use for the tile's height from ground level), so adding this onto the value of fy gives the following final position of the mouse map:
Here is a table of the changes to the fine X and Y co-ordinates, assuming that the tile width is 32, and thus the mouse maps are 32 x 32: