1

tileWidth is 64 and tileHeight is 32.

This is my map array:

var map:Array=
    [
        [2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2],
        [2,3,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2],
        [2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2],
        [2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2],
        [2,2,2,2,2,2,2,2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2]
    ];

Here is how theyre being placed:

//place tiles
        for (var i:Number = 0; i < map.length; i++)
        {
            for (var j:Number = 0; j < map[i].length; j++)
            {
                placeTile(map[i][j],i,j);
            }
        }

//place the tile based on coordinates
    private function placeTile(id:uint,i:uint,j:uint)
    {
        var pos:Point=new Point();
        pos.x = i;
        pos.y = j;
        pos = twoDToIso(pos);

        tile = new MovieClip(atlas.getTextures(getTile(id)),20);
        tile.x = pos.x ;
        //tile.y = pos.y + (map.length/2)*tileHeight - tileHeight*4 ;//used to center
        tile.y = pos.y;
        tile.addEventListener(TouchEvent.TOUCH, mapDown);
        mapContainer.addChild(tile);
    }

This is the function used to plot out the 2d points to isometric:

//CONVERT POINT TO ISOMETRIC
    private function twoDToIso(pt:Point):Point
    {
        trace(" ");
        trace("twoDtoIso:");
        trace("2d: " + pt);
        var tempPt:Point = new Point(0,0);

        tempPt.x = (pt.x * tileWidth / 2) + (pt.y * tileWidth / 2);
        tempPt.y =  (pt.y * tileHeight / 2) - (pt.x * tileHeight / 2);


        trace("iso: " + tempPt);
        return (tempPt);
    }

What formula can I use to revert the coordinates I receive when clicking a tile, back to 2d / access to the map array?

user4179189
  • 13
  • 1
  • 3
  • Correct your tags. "iso" has nothing to do with it. "cartesian" is kind of the opposite of "isometric". You forgot a (*any*) language tag. Finally, did you attempt anything? – Jongware Oct 24 '14 at 21:13
  • I've attempted a lot. Language isn't necessary as it would just be a formula. If I can retrieve the isometric coordinates from array indexes then I should be able to revert the coordinates I get by clicking to access the array. tempPt.x=Math.floor(pt.x/tileHeight); tempPt.y=Math.floor(pt.y/tileHeight); This seems to only work if the screen itself was a grid, not for the tiles being placed isometrically. – user4179189 Oct 24 '14 at 21:19

1 Answers1

0

The transformation from screen coordinates back to isometric is the inverse of your own twoDToIso: for every 2 pixels across the x axis, you subtract 1 from the y axis, so for the reverse you do the same for pixels across the y axis. (Hope that's as clear as I think it is.)

However, the signs of the calculations depend on how your map is set up: with the x axis going diagonally up to the right, or down to the right (and, possibly, the same for y). I did my testing with a diagonal up-map, with y counting up to the lower right:

             +x
          ..
       2,0   ..
   1,0   2,1    ..
0,0   1,1   2,2    ..
   0,1   1,2   ..
      0,2   ..
         ..+y

If your map is drawn differently, swap the signs for the x,y calculations (and possibly for the constant 32 as well).

The conversion from mouse coordinates mx,my to isometric coordinates tilex,tiley is the following:

int tilex = mx - 2*my + 32;
int tiley = mx + 2*my - 32;

tilex /= 64;
tiley /= 64;

drawcursor (tilex, tiley);

and is pixel-perfect for tiles of 128x64:

isometric cursor movement

Moving the mouse cursor only one pixel lower will select the blank space to the right and below the blue selected tile.

There is a small oddity here: the black space in the lower half of my image is "negative x", and when entering that, the cursor needs a further adjustment of +1 for the isometric x position. This is because in C[*] by default an integer is rounded "towards zero". Using floats and floor made it work; but in general, you should strive to use integers for frequent calculations such as these. (Also, I don't think that a negative x or y position would be valid in regular tile maps.)

[*] I wrote my test program with C and SDL.

If you want to be able to select individual pixels inside each tile (for instance, if you want to select a certain quarter of a tile), you can use the fractional part of tilex and tiley:

innerx = tilex & 63;
innery = tiley & 63;

before doing the division by 64.

Jongware
  • 22,200
  • 8
  • 54
  • 100
  • It makes sense looking at it, but i really can't get this thing to work, it's frustrating me. I'm using feathers with starling / flash. For some reason I can't place objects with negative values in the scrollContainer so I give each y value an increase of 512 (this centers the 40 tile long map on the screen). I'm assuming that is what is giving me wonky values. But I adjust the 512 before calculating. [0,0,0] [0,1,0] [0,0,1] This will draw the 1 tiles down and to the right the way my map is being drawn. – user4179189 Oct 26 '14 at 20:31
  • Well .. adjusting your y position by 512 *should* not make a difference (subtract 512 from the mouse y position before doing my calculation). The problem may lie, as I already noted, in the orientation of your map. I moved mine around to draw back-to-front. – Jongware Oct 26 '14 at 22:24
  • Alright thanks for the detailed response. I'll give it another by redoing it all and starting fresh, hopefully it works out. – user4179189 Oct 27 '14 at 01:58