Results 1 to 10 of 10

Thread: ISO coordinates

  1. #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. #2
    Legendary Member cairnswm's Avatar
    Join Date
    Nov 2002
    Location
    Randburg, South Africa
    Posts
    1,537

    ISO coordinates

    [pascal]function TDXCGIsoMap.PointToCell(X,Y : Integer): TPoint;
    Var
    BX,BY,CX,CY,DX,DY,AD, BD : Integer;
    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;
    If AD < BD then
    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.
    William Cairns
    My Games: http://www.cairnsgames.co.za (Currently very inactive)
    MyOnline Games: http://TheGameDeveloper.co.za (Currently very inactive)

  3. #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.
    [size=10px][ Join us in #pgd on irc.freenode.net ] [ Sign the Petition for a Software Patent Free Europe ][/size]

  4. #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. #5

    ISO coordinates

    I found an old program I wrote that demonstrates converting iso coodinates:
    IsoDemo.zip (6 KB)
    [size=10px][ Join us in #pgd on irc.freenode.net ] [ Sign the Petition for a Software Patent Free Europe ][/size]

  6. #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. #7

    ISO coordinates

    Quote 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.
    [size=10px][ Join us in #pgd on irc.freenode.net ] [ Sign the Petition for a Software Patent Free Europe ][/size]

  8. #8

    ISO coordinates

    oh
    and how can I solve ?

  9. #9
    Legendary Member cairnswm's Avatar
    Join Date
    Nov 2002
    Location
    Randburg, South Africa
    Posts
    1,537

    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
    if isoPointInQuad(
    (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.
    William Cairns
    My Games: http://www.cairnsgames.co.za (Currently very inactive)
    MyOnline Games: http://TheGameDeveloper.co.za (Currently very inactive)

  10. #10

    ISO coordinates

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

Bookmarks

Posting Permissions

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