The forums have permanently moved to forum.kirupa.com. This forum will be kept around in read-only mode for archival purposes. To learn how to continue using your existing account on the new forums, check out this thread.


Results 1 to 5 of 5

Thread: Picking Tile in staggered isometric map

  1. #1

    Picking Tile in staggered isometric map

    Hello!
    I have been looking and trying for quite a while now, but can't seem to work out an algorithm for figuring out which tile is selected on a staggered isometric map using 64x32 tiles with a diamond shape inside.

    Here is a pic of my map...


    The first row is drawn, then the x is offset to the right by 32 and the next row is drawn.

    Anyone have any good math skills to throw some algorithms my way for this?
    Thanks for any help!

    PS: My math isn't exactly top notch, so please keep that in mind. Smiley

  2. #2
    Hello there, I might be able to help a little bit or atleast get you thinking in the right direction,

    EDIT: And I just saw you are naming the tiles with x and y areas, therefore, the hitTest approach in the second paragraph might be easier to implement.
    How are the tiles being selected? The mouse? In any case the easiest way I can think to do it would be to call a .hitTest() to check and see if it is hitting each tiles. The downside to this would be that it would run rather slow. If you're making a game I wouldn't suggest using a hitTest().
    On the thought of a hitTest() you could minimize the amount of hitTests used. For instance, if the mouse is clicked at x = 254 and y = 350 and you're tiles are each 35 high and 35 across, you could figure out aprroximately which tile it is.
    What I mean is that you could name each tile something like "Tile_"+x+"_"+y so the first one would be Tile_0_0 and it would increment the x and y. Then, you could take the x Value divided by the tileWidth and use Math.floor. So Math.floor(254 / 35) = 7. You would know that the click took place on either tile 6, 7, or 8... (On a square map it would be 7, but since it's isometric you can't be sure). Then you can repeat the same step with the y value and just run hitTests on the tiles with the x value plus or minus 1 and the y value plus or minus 1, so in this case you would check Tile_6_y, Tile_7_y, Tile_8_y. I'm not sure if this helps. This would at least lower the amount of hitTests that would be called.
    If this doesn't help sorry, but hopefully it will get you thinking the right way. Also, I'll keep thinking about how you might be able to do this without hitTests.
    SoupHead

  3. #3
    Maybe try something like this...
    Code:
    var tileW = 64;
    var tileH = 32;
    var rows = 8;
    var cols = 4;
    
    for (var i = 0; i < rows; ++i) {
            for (var j = 0; j < cols; ++j) {
                    tTile = _root.attachMovie("Tile", "R" + i + "C" + j, _root.getNextHighestDepth());
                    tTile._x = (tileW * j) + ((i % 2 == 1) ? 32 : 0);
                    tTile._y = (tileH / 2) * i;
            }
    }
    onMouseDown = function () {
            var ax, ay, bx, by;
            var cx = _xmouse;
            var cy = _ymouse;
            var posX = (_xmouse / 32) >> 0;
            var posY = (_ymouse / 16) >> 0;
            if ((posX % 2) == (posY % 2)) {
                    ax = (posX) * 32;
                    ay = (posY + 1) * 16;
                    bx = (posX + 1) * 32;
                    by = (posY) * 16;
                    if (getPos(ax, ay, bx, by, cx, cy) < 0) {
                            trace(((posY / 1 >> 0) - 1) + " : " + ((posX / 2 >>0) + ((((posY / 1 >> 0) - 1) % 2 == 0) ? 0 : -1)));
                    } else {
                            trace((posY / 1 >> 0) + " : " + (posX / 2 >> 0));
                    }
            } else {
                    ax = (posX) * 32;
                    ay = (posY) * 16;
                    bx = (posX + 1) * 32;
                    by = (posY + 1) * 16;
                    if (getPos(ax, ay, bx, by, cx, cy) < 0) {
                            trace(((posY / 1 >> 0) - 1) + " : " + (posX / 2 >>0));
                    } else {
                            trace((posY / 1 >> 0) + " : " + ((posX / 2 >> 0) +((((posY / 1 >> 0) - 1) % 2 == 0) ? -1 : 0)));
                    }
            }
    };
    function getPos($ax, $ay, $bx, $by, $cx, $cy) {
            // below = 1, above = -1, on = 0;
            var slope = ($by - $ay) / ($bx - $ax);
            var yIntercept = $ay - $ax * slope;
            var cSolution = (slope * $cx) + yIntercept;
            if (slope != 0) {
                    if ($cy > cSolution) {
                            return $bx > $ax ? 1 : -1;
                    }
                    if ($cy < cSolution) {
                            return $bx > $ax ? -1 : 1;
                    }
                    return 0;
            }
            return 0;
    }

  4. #4
    Wow,
    You are the man! I am not even gonna post the embarrassing hack I was attempting compared to this little picasso you have posted.
    I really, really appreciate the help and the contribution. I could've spent a lifetime on this and never came up with such an elegant solution. This works great!!

    If you don't mind, I am going to post this in all the different forums where people were offering help. Your name may get put in the history books of legends!! lol. I will also post this on my own forums under tutorials so that when I run into this same problem a year or so from now, and I forget the solution, I can easily reference it.

    Thank you soooo much for the help!!

  5. #5
    yes i have also try these code but working is not properly.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Tags for this Thread

Posting Permissions

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

Home About kirupa.com Meet the Moderators Advertise

 Link to Us

 Credits

Copyright 1999 - 2012