So I've managed myself to write the first part (algorithm) to calculate each tile's position where should it be placed while drawing this map (see bellow). However I need to be able to convert mouse location to the appropriate cell and I've been almost pulling my hair off because I can't figure out a way how to get the cell from mouse location. My concern is that it involves some pretty high math or something i'm just something easy i'm not capable to notice.
For example if the mouse position is 112;35 how do i calculate/transform it to to get that the cell is 2;3 at that position?
Maybe there is some really good math-thinking programmer here who would help me on this or someone who knows how to do it or can give some information?
var cord:Point = new Point();
cord.x = (x - 1) * 28 + (y - 1) * 28;
cord.y = (y - 1) * 14 + (x - 1) * (- 14);
Speaking of the map, each cell (transparent tile 56x28 pixels) is placed in the center of the previous cell (or at zero position for the cell 1;1), above is the code I use for converting cell-to-position. I tried lot of things and calculations for position-to-cell but each of them failed.
Edit: After reading lot of information it seems that using off screen color map (where colors are mapped to tiles) is the fastest and most efficient solution?
I know this is an old post, but I want to update this since some people might still look for answers to this issue, just like I was earlier today. However, I figured this out myself. There is also a much better way to render this so you don't get tile overlapping issues.
The code is as simple as this:
mouse_grid_x = floor((mouse_y / tile_height) + (mouse_x / tile_width));
mouse_grid_y = floor((-mouse_x / tile_width) + (mouse_y / tile_height));
mouse_x
and mouse_y
are mouse screen coordinates.
tile_height
and tile_width
are actual tile size, not the image itself. As you see on my example picture I've added dirt under my tile, this is just for easier rendering, actual size is 24 x 12. The coordinates are also "floored" to keep the result grid x and y rounded down.
Also notice that I render these tiles from the y=0 and x=tile_with / 2 (red dot). This means my 0,0 actually starts at the top corner of the tile (tilted) and not out in open air. See these tiles as rotated squares, you still want to start from the 0,0 pixel.
Tiles will be rendered beginning with the Y = 0 and X = 0 to map size. After first row is rendered you skip a few pixels down and to the left. This will make the next line of tiles overlap the first one, which is a great way to keep the layers overlapping coorectly. You should render tiles, then whatever in on that tile before moving on to the next.
I'll add a render example too:
for (yy = 0; yy < map_height; yy++)
{
for (xx = 0; xx < map_width; xx++)
{
draw tiles here with tile coordinates:
tile_x = (xx * 12) - (yy * 12) - (tile_width / 2)
tile_y = (yy * 6) + (xx * 6)
also draw whatever is on this tile here before moving on
}
}
(1) x` = 28x -28 + 28y -28 = 28x + 28y -56
(2) y` = -14x +14 +14y -14 = -14x + 14y
Transformation table:
[x] [28 28 -56 ] = [x`]
[y] [-14 14 0 ] [y`]
[1] [0 0 1 ] [1 ]
[28 28 -56 ] ^ -1
[-14 14 0 ]
[0 0 1 ]
Calculate that with a plotter ( I like wims )
[1/56 -1/28 1 ]
[1/56 1/28 1 ]
[0 0 1 ]
x = 1/56*x` - 1/28y` + 1
y = 1/56*x` + 1/28y` + 1
I rendered the tiles like above.
the sollution is VERY simple!
first thing:
my Tile width and height are both = 32 this means that in isometric view, the width = 32 and height = 16! Mapheight in this case is 5 (max. Y value)
y_iso & x_iso == 0 when y_mouse=MapHeight/tilewidth/2 and x_mouse = 0
when x_mouse +=1, y_iso -=1
so first of all I calculate the "per-pixel transformation"
TileY = ((y_mouse*2)-((MapHeight*tilewidth)/2)+x_mouse)/2;
TileX = x_mouse-TileY;
to find the tile coordinates I just devide both by tilewidth
TileY = TileY/32; TileX = TileX/32;
DONE!! never had any problems!
I've found algorithm on this site http://www.tonypa.pri.ee/tbw/tut18.html. I couldn't get it to work for me properly, but I change it by trial and error to this form and it works for me now.
int x = mouse.x + offset.x - tile[0;0].x; //tile[0;0].x is the value of x form witch map was drawn
int y = mouse.y + offset.y;
double _x =((2 * y + x) / 2);
double _y= ((2 * y - x) / 2);
double tileX = Math.round(_x / (tile.height - 1)) - 1;
double tileY = Math.round(_y / (tile.height - 1));
This is my map generation
for(int x=0;x<max_X;x++)
for(int y=0;y<max_Y;y++)
map.drawImage(image, ((max_X - 1) * tile.width / 2) - ((tile.width - 1) / 2 * (y - x)), ((tile.height - 1) / 2) * (y + x));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With