EDIT Adjusted all the algorithms posted. It's now working NEARLY flawlessly. It's just the left-most 9 tiles that it fails on (A picture is at the bottom). It selects the completely wrong tile in most cases when hovering one of those nine.
EDIT2 I'm almost certain now that the problem is due to errors when screenX or screenY are negative, so it's probably down to using math.abs on tilePixelX/Y, but it can't just be that, otherwise the results wouldn't be so far off (Although it could well be contributing)
I'm making an isometric game, and right now I'm working on the map rendering engine. In theory it should be fairly simple but I just can't get the tile coords from the mouse position.
My tiles are 64 wide and 32 tall. An image is shown below:
My map displays fairly perfectly:
The actual problem is explained at the top.
Here's the code I'm using right now:
int screenX = sf::Mouse::getPosition(window).x - 250;
int screenY = sf::Mouse::getPosition(window).y - 250;
int tilex = floor((screenY / 32) + (screenX / 64));
int tiley = floor((screenY / 32) - (screenX / 64));
int tilePixelX = abs(screenX % 64); // I believe part of the problem
int tilePixelY = abs(screenY % 32); // is absoluting these. Not all though.
sf::Color mCol = mouseMap.getPixel(tilePixelX, tilePixelY);
if (mCol.r == 20)
tilex -= 1;
else if (mCol.r == 40)
tiley -= 1;
else if (mCol.r == 60)
tilex += 1;
else if (mCol.r == 80)
tiley += 1;
I'm now using a mousemap which is working fantastic however as said above it's still failing on the left-most nine tiles in the diamond (When you hover them it selects a seemingly random around 4-5 tiles away, or no tile at all (I'm guessing out of bounds of the map):
That also shows the problem tiles highlighted in red.
This is what the map looks like, to give you an idea of how my rendering engine works. Note that transparent pixels are considered empty, and black pixels are considered walls (Which I did not render for the example picture above, so none of the tiles displayed on the picture above are 0th-column or 0-th row, nor are they the last row.
My mouse map is definitely correct due to most of the map working but here it is anyway:
Edit:
I've packaged the necessary files and DLLs into a zip file so you can run it and see for yourself what is going on:
https://dl.dropbox.com/u/37019412/Broken.zip
Drawing formula is:
(x - y) * 32 + 250, (x + y) * 16 + 250
Where before coma is X and after is Y and inside x and y are the tile coordinates.
In the end it was due to a lot of rounding errors.
if (screenX < 0 || tilePixelX < 0)
tilePixelX = 64 - abs(tilePixelX);
if (screenY < 0 || tilePixelY < 0)
tilePixelY = 32 - abs(tilePixelY);
if (tilePixelX >= 64)
tilePixelX = 63;
if (tilePixelY >= 32)
tilePixelY = 31;
if (screenX < 0 || screenY < 0)
{
tilex--;
tiley++;
}
Sorted it out, even if it was a little bit of an ugly hack in places.