1. ## ISO coordinates

Hi all,
I want to retrieve the selected tile -record- (eg: clicked by mouse, with X and Y of mouse pointer) in an isometric map. How can I do this?

Example:

[pascal]
...

type
TIsoTile = record
image: integer;
zoffset: integer;
selected: boolean;
end;

...

procedure TForm1.DXDrawMouseDown(Sender: TObject; Button:
TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
IsoMap[ISOCoordX(x, y, isowidth, isoheight), ISOCoordY(x, y,
isowidth, isoheight)].image := 1;
end;
[/pascal]

Thanks.

PS: sorry for my english

2. ## ISO coordinates

[pascal]function TDXCGIsoMap.PointToCell(X,Y : Integer): TPoint;
Var
begin
X := X + MapLeft+32;
Y := Y + MapTop;
Y := Y - 192;
BX := X div 128;
BY := (Y div 64)*2;
DX := ABS(((BX * 12 + 64) - X);
// DY := ABS((((BY * 64) - 224)) - Y);
DY := ABS((((BY div 2) * 64) + 32) - Y);
AD := DX + 2 * DY;
X := X - 64;
Y := Y + 32;
CX := X div 128;
CY := (Y div 64) * 2 - 1;
DX := ABS(((CX * 12 + 64) - X);
DY := ABS((((CY div 2) * 64) + 96) - Y);
BD := DX + 2 * DY;
Begin
Result := Point(BX,BY);
End
Else
Begin
Result := Point(CX,CY);
End;
end;
[/pascal]

My tiles were 128*64

Basically the logic I used was
- Every point could be in one of two different tiles.
- Identify these two tiles
- work out distance to center
- closest to center was the tile I wanted.

Not very clear I know but I hope it helps.

3. ## ISO coordinates

If you are using a diamond shaped map (a la Age of Empires), this should work:
[pascal]
procedure MapToScreen(MapX, MapY: Double; out ScreenX, ScreenY: Integer);
begin
ScreenX := Trunc(32 *(MapY + MapX))- OffsetX;
ScreenY := Trunc(16 *(MapY - MapX))- OffsetY;
end;

procedure ScreenToMap(ScreenX, ScreenY: Integer; out MapX, MapY: Double);
var
t1, t2: Integer;
begin
t1 := ScreenX + OffsetX;
t2 := 2 *(ScreenY + OffsetY);
MapX := (t1 - t2)/ 64;
MapY := (t1 + t2)/ 64;
end;
[/pascal]
OffsetX and OffsetY indicate the position of the top-left corner of the screen relative to the origin of the map, which was considered to be the far left corner of the map. Each tile is considered to be 1 unit in each direction; with the x-axis running from the left corner to the top corner, and the y-axis running from the left to the bottom.

This code is for 64x32 pixel tiles; you would need to adjust things a little if you were using different sizes. The screen to map function was come up with by algebraically rearranging the map to screen function.

Also, these only work for flat maps; maps with a height component are more complicated as a click could have been in different tiles on different layers.

4. ## ISO coordinates

You should be converting iso coordinates to screen coordinates when drawing, take that code and do everything the other way around

5. ## ISO coordinates

I found an old program I wrote that demonstrates converting iso coodinates:
IsoDemo.zip (6 KB)

6. ## ISO coordinates

Thanks all!
But... I have some problems with the code.

Look at
http://www.tntdeveloping.com/jvcl/iso4.zip
and compile.

With this function CellAt, I have the same problem with your code.
Some tiles are translated by x + 1!!! :cry:

How can I solve?

Thank you for the help.

7. ## ISO coordinates

Originally Posted by peste1
Thanks all!
But... I have some problems with the code.

Look at
http://www.tntdeveloping.com/jvcl/iso4.zip
and compile.

With this function CellAt, I have the same problem with your code.
Some tiles are translated by x + 1!!! :cry:

How can I solve?

Thank you for the help.
That is the trouble with using a 'rectangular' map with iso tiles; it is much easier to have a 'diamond' shaped map.

8. ## ISO coordinates

oh
and how can I solve ?

9. ## ISO coordinates

Change your Test procedure like this

[pascal]procedure Test;
var
visx, visy, loopx, loopy : integer;
IsoHeight, IsoWidth, FCellWidthDiv2, FCellHeightDiv2: integer;
begin
IsoWidth := 64;
IsoHeight := 32;
FCellWidthDiv2 := IsoWidth div 2;
FCellHeightDiv2 := IsoHeight div 2;
Point.x := Point.x; //+ (FXOffset + ScrollXOffset);
Point.y := Point.y; //+ (FYOffset + ScrollYOffset);
result.X := -1; // set no tile
result.y := -1;
if (isowidth = 0) then Exit;
visx := MaxInt(0, Point.x div IsoWidth - 1); // guess what tile left
visy := MaxInt(0, Point.y div (FCellheightdiv2) - 1); // guess what tile top
for loopy := visy - 1 to // just loop through 9 tiles
MinInt(MaxMapHeight, visy + 1) do
for loopx := visx - 1 to
MinInt(MaxMapWidth, visx + 1) do
(loopx * IsoWidth) + ((loopy mod 2) * (FCellwidthdiv2)),
(loopy * (FCellheightdiv2)) + (FCellheightdiv2),
(loopx * IsoWidth) + ((loopy mod 2) * (FCellwidthdiv2)) + (FCellwidthdiv2),
(loopy * (FCellheightdiv2)) + IsoHeight,
(loopx * IsoWidth) + ((loopy mod 2) * (FCellwidthdiv2)) + IsoWidth,
(loopy * (FCellheightdiv2)) + (IsoHeight div 2),
(loopx * IsoWidth) + ((loopy mod 2) * (FCellwidthdiv2)) + (FCellwidthdiv2),
(loopy * (FCellheightdiv2)),
Point.x, Point.y) then
begin
If loopy mod 2 = 1 then
result.x := loopx + 1
else
result.x := loopx;
result.y := loopy + 1;
Exit;
end;
end; // get co-ords relative to tile
[/pascal]

This is the bit that changed:

[pascal] If loopy mod 2 = 1 then
result.x := loopx + 1
else
result.x := loopx;[/pascal]

Basically it says if a line os offset by one tile to the right then dont add the one to the X coordinates.

10. ## ISO coordinates

:shock:
Thanks thanks thanks!!! :!:

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•