Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Point in tile isometric diamond map

Credits go to HoHo and Sirocco for helping out!
This thread is locked; no one can reply to it. rss feed Print
Point in tile isometric diamond map
Rick
Member #3,572
June 2003
avatar

Is it possible to find what tile the mouse is in on an isometric diamond shaped map with a calculation instead of having to loop through each tile and figuring it out? Much like a square tile map you can do:

row = (int)mouse_x/TILE_H;
col = (int)mouse_y/TILE_W;

[EDIT]

I guess if things are easier in a staggered isometric map I'd be open to that also. I have just never worked on those before.

========================================================
Actually I think I'm a tad ugly, but some women disagree, mostly Asians for some reason.

HoHo
Member #4,534
April 2004
avatar

use a mouse lookup map
http://www.gamedev.net/reference/articles/article2026.asp

I've done it in an Xcom-like engine and it worked rather fine. I'd give you a link to the sources I once attached to a post but it seems like the links are broken and I can't find that post. I can upload it later today if you want to.

[edit]

Actually I meant this article but the first one can be useful too. This one also has formula for finding the tile coordinates from screen coordinates

__________
In theory, there is no difference between theory and practice. But, in practice, there is - Jan L.A. van de Snepscheut
MMORPG's...Many Men Online Role Playing Girls - Radagar
"Is Java REALLY slower? Does STL really bloat your exes? Find out with your friendly host, HoHo, and his benchmarking machine!" - Jakub Wasilewski

Sirocco
Member #88
April 2000
avatar

You've got a couple of options depending on the complexity of the map. You can create a lookup table using various methods. Some are more memory efficient than others. There are some techniques you could investigate using rays to trace the route to the 'monitor', which I've used with varying degrees of success.

At the end of the day, a lookup table would probably be your best bet.

-->
Graphic file formats used to fascinate me, but now I find them rather satanic.

Rick
Member #3,572
June 2003
avatar

I've looked at the second article (Out With the Old, In With the New) which shows how to find the tile the mouse is in via a simple calculation, but I'm not sure about the drawing of the diamond tilemap that matches that code. You seem to have to draw the first tile 1/2 way into the top left screen.

========================================================
Actually I think I'm a tad ugly, but some women disagree, mostly Asians for some reason.

HoHo
Member #4,534
April 2004
avatar

Quote:

I'm not sure about the drawing of the diamond tilemap that matches that code. You seem to have to draw the first tile 1/2 way into the top left screen.

I don't understand. The ideas from the second article should work with pretty much anything. I copied them almost directly to my engine that supported diamond shape maps, multiple levels and per-pixel scrolling. Result was something like this:
{"name":"dagame.PNG","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/6\/2\/62883d2af523cf4b80b7faefda8e980b.png","w":664,"h":515,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/6\/2\/62883d2af523cf4b80b7faefda8e980b"}dagame.PNG

__________
In theory, there is no difference between theory and practice. But, in practice, there is - Jan L.A. van de Snepscheut
MMORPG's...Many Men Online Role Playing Girls - Radagar
"Is Java REALLY slower? Does STL really bloat your exes? Find out with your friendly host, HoHo, and his benchmarking machine!" - Jakub Wasilewski

Rick
Member #3,572
June 2003
avatar

Here is the complete code and it doesn't seem to work. I just copied the code on that page and plugged it in. When I clicked the top tile I get mapx = 34, and mapy = 2, which isn't right. I'm expecting 0,0. I must be doing something wrong.

[EDIT]
Revised code as he had some bugs in it. Now mapx is 0 which is right but mapy is -1 which isn't right.

[EDIT2]
I think I got it. I had to put my xadjust to 32 (1/2 tile width) so it would make the first tile being drawn half off the screen.

Bascially changed:
pointer_get_map_coords(mouse_x, mouse_y, 0, 0, 0, 0, &mapx, &mapy);
to
pointer_get_map_coords(mouse_x, mouse_y, 32, 0, 0, 0, &mapx, &mapy);

and it works now. Thanks all.

1#include "allegro.h"
2 
3#define TILE_W 64
4#define TILE_H 32
5#define MAP_ROW 10
6#define MAP_COL 10
7 
8BITMAP *buffer, *tile;
9 
10 
11void drawMap()
12{
13 int row, col, x, y;
14 
15 for(row=0;row<MAP_ROW;row++)
16 {
17 for(col=0;col<MAP_COL;col++)
18 {
19 //convert map to screen
20 x = col*(TILE_W/2) - row*(TILE_W/2);
21 y = col*(TILE_H/2) + row*(TILE_H/2);
22 
23 draw_sprite(buffer, tile, x, y);
24 }
25 }
26}
27 
28void flip()
29{
30 draw_sprite(buffer, mouse_sprite, mouse_x, mouse_y);
31 blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
32 clear(buffer);
33}
34 
35void pointer_get_fine_map_coords(short pointer_xpos, short pointer_ypos,
36 signed short xadjust, signed short yadjust,
37 short center_x, short center_y,
38 signed short *mapx,signed short *mapy)
39{
40 signed short xo, yo;
41 signed short x, y;
42 
43 // get the x and y positions on screen relative to scroll and center coords
44 xo = pointer_xpos - (center_x + xadjust);
45 yo = pointer_ypos - (center_y + yadjust);
46 
47 // start to figure the map coordinates
48 x = yo + (xo/2);
49 y = yo - (xo/2);
50 
51 // store the results
52 *mapx = (signed short)x;
53 *mapy = (signed short)y;
54}
55 
56void pointer_get_map_coords(short pointer_xpos, short pointer_ypos,
57 signed short xadjust, signed short yadjust,
58 short center_x, short center_y,
59 signed short *mapx,signed short *mapy)
60{
61 signed short x, y;
62 
63 pointer_get_fine_map_coords(pointer_xpos, pointer_ypos,
64 xadjust, yadjust,
65 center_x, center_y,
66 &x, &y);
67 
68 if(x < 0)
69 x -= 31;
70 if(y < 0)
71 y -= 31;
72 
73 x /= 32;
74 y /= 32;
75 
76 *mapx = (signed short)x;
77 *mapy = (signed short)y;
78}
79 
80void input()
81{
82 signed short mapx, mapy;
83 int i;
84 
85 if(mouse_b & 1)
86 {
87 pointer_get_map_coords(mouse_x, mouse_y, 0, 0, 0, 0, &mapx, &mapy);
88 i = 0;
89 }
90}
91 
92 
93 
94void init()
95{
96 allegro_init();
97 install_keyboard();
98 install_timer();
99 install_mouse();
100 set_color_depth(16);
101 set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800,600,0,0);
102 buffer = create_bitmap(SCREEN_W, SCREEN_H);
103 clear(buffer);
104 
105 tile = load_bitmap("C:\\tile.bmp", NULL);
106}
107 
108 
109int main()
110{
111 init();
112 
113 while(!key[KEY_ESC])
114 {
115 input();
116 drawMap();
117 flip();
118 }
119 
120 return 0;
121 
122}END_OF_MAIN()

========================================================
Actually I think I'm a tad ugly, but some women disagree, mostly Asians for some reason.

Wilson Saunders
Member #5,872
May 2005
avatar

When I made my Isometric tileing engine I had two grids of tiles the first with no offset and the other offset by 1/2 the width and 1/2 the height. The tiles were bitmaps with magenta 0xff00ff as the non diamond section. So individually the grids would draw a checkered pattern but toggether they draw the full ground.

Any to get to your question. You find the which node in each grid the mouse is closest to like:

int grid1indexX = mouse_x/TILE_WIDTH;
int grid1indexY = mouse_y/TILE_HEIGHT;

int grid2indexX = (mouse_x + TILE_WIDTH/2)TILE_WIDTH;
int grid2indexY = (mouse_y + TILE_HEIGHT/2)TILE_HEIGHT;

Then you decide which grid tile you are going to use like this

if( grid1[grid1indexX][grid1indexY]->DistanceTo(mouse_x, mouse_y) <
    grid2[grid2indexX][grid2indexY]->DistanceTo(mouse_x, mouse_y) )
{
    // use grid 1 tile
} else {
    // use grid 2 tile
}

Hope this helps

________________________________________________
Play my games at http://monkeydev.com

Go to: