Game Development Community

dev|Pro Game Development Curriculum

Interleaved tile rendering in t2dTileMap

by Neo Binedell · 07/30/2005 (3:03 pm) · 38 comments

This resource is outdated and will not be updated any further as I have started a brand new iso pack from scratch.

You can read more here

~neo


  • in the beginning...

  • One of the first things I did when I got T2D was to play with ideas for isometric tiles, etc.
    I won't bore you with all the other things I tried but skip to the first (and then last) idea:

    I've extended t2dTileMap and t2dTileLayer to provide built-in interleaved offsetting. I chose to do it by
    deriving 2 classes nxIsoTileMap and nxIsoTileLayer from their respective T2D counterparts and only overriding
    the specific methods that deal with rendering and picking of tiles. Although this could be integrated quite easily into
    t2dTileLayer I preferred to do it this way as it is a lot cleaner and we don't have to keep patching the source
    each time we update from cvs. It also makes it super easy to intergrate, simply drop the source files in your project
    and add a lil something to the tile editor GUI and you're in the game.

    If you're not too clear on what all this means lemme throw some pics at ya:


    A normal grid with isometric tiles looks like this:

    [note: will add images later, in the meantime enjoy the ascii version ;p]

    /\/\/\/\   ___ row 0
    \/\/\/\/
    /\/\/\/\   ___ row 1
    \/\/\/\/

    But what we want is to offset each alternate row of tiles so it fits snugly in between the row above and the row below,
    which you can fake with two overlapping layers with tiles in alternate positions:

    /\/\/\/\    ___ row 0
    \/\/\/\/\   ___ row 1
     \/\/\/\/
    If you step through the layout of the tiles you'll find the following:

    We start as normal with row 0: X = 0, Y = 0
    We tile that row as usual by adding TileWidth to X each time
    For the next row, we want to interleave the tiles so we first
    offset X by half a TileWidth, and we increment Y by TileHeight / 2,
    then just tile the row again by adding TileWidth to X
    Rinse and repeat.

    for( all tiles in Y )
       {
           if( Y % 2 ) // is this an odd row?
               offsetX = TileWidth / 2
           else
               offsetX = 0
    
           for( all tiles in X )
           {
                 draw tile at XY
    
                 X += TileWidth
           }
    
           Y += TileHeight / 2
       }

    Note that we ONLY offset the output coords... basically we are mapping the normal tile grid to an
    interleaved output grid. Also this really has nothing to do with the isometric part of the deal
    beyond allowing interleaving tiles, you can choose what view angle you want by choosing
    the appropriate tile height and width ratio.

    So the only render code that really had to change was the part where we incremented the output X and Y coords.
    Oh yes, and the grid overlay drawing which I also changed, I wont go into the details of that just yet but I'll post
    a piccy of it in the tile editor to show u what I mean as soon as I get time to put it up.

    As it stands at the moment to use it you do this:

    %map = new nxIsoTileMap(){ scenegraph = t2dScene; }
    
    %layer = %map.createTileLayer( "16 16 32 16" );

    Everything else works exactly the same from there on ;p

    Next I tackled the pickTile() part which is basically just mapping the world coords to the correct position on
    our new interleaved grid layout which I'll wax lyrically about later.

    Other things I will be tackling is of course the all important depth-sorting issues for rendering things correctly.

    I plan on posting a little demo app once its ready which will hopefully help anyone trying to do isometric stuff in
    T2D.

    Just goes to show you can do anything in T2D ;p

    For now here's some pics to give you an idea:

    In the beginning:

    www.neoji.co.za/neo/gg/isotiler0.jpg
    And then there was stuff:

    www.neoji.co.za/neo/gg/isotiler1.jpg
    And he said let there be height:

    www.neoji.co.za/neo/gg/isotiler2.jpg
    Hide that pesky grid:

    www.neoji.co.za/neo/gg/isotiler3.jpg
    As you can see I've added arbitrary height to the tile renderer, which allows
    you to have things like tall walls and towers, etc. This basically just lets us draw
    "up" from the tile base.

    Gotta love experimenting with arb stuff heheh...

    update 2005-08-25:

    Back from another holiday and before I get stuck in again I'll explain a bit about the tile picking.

    Here's an excerpt from the comments I have in the source:

    *	Due to the interleaved nature of the the tessellation we cant just pick
    //		a specific tile by using a simple formula. What we do know however is that
    //		every alternate tile falls withing the rectangular grid. So first we pick
    //		the rectangular grid area the point is in, then find out if it hit the actual
    //		"diamond" in the "center" of that grid tile. If not it has to fall in one of the
    //		four quadrants topleft,topright,bottomleft or bottomright of the diamond. We find
    //		that by offsetting the local origin to the center of the tile and simply testing
    //		which side of the center "diamond" edges the point falls by comparing against the
    //		slope of that edge using one of the standard forms of the line equation:
    //
    //		Y = MX + C
    //
    //		where:
    //			M	=	slope (Y/X)
    //			X	=	X value of pick point to plug in
    //			C	=	Y intercept (where line crosses Y)
    //		 
    //		|a/\b|	
    //		|/  \|
    //		|\  /|
    //		|c\/d|
    //
    //    So if our point fell in a we'd pick the tile to the top left of this rectangular grid tile, etc, etc.

    I created a little flash app to test and implement my theory and you can have a squiz at it here

    Love using flash for prototyping stuff quickly and it was rather easy to integrate into C++ thereafter.

    Next on my list is sorting out the artifacts I get in the editor when moving the layer, layer independent sorting, etc.

    I had an idea for an lazy way to solve the depth sorting issue, i.e. don't sort at all.
    Instead of drawing each layer one after another, we interleave the drawing so we draw one row from each iso layer (as well as sprite layers). This should automagically hide objects by overdraw.
    After looking at the way the scenegraph works I realized that we cant really do that as each object gets asked to do its rendering and thats that. I wouldn't want to start hacking at that level just for the iso stuff though (it would be tacky ;),
    so I thought perhaps create a container object that houses all the isolayers, which could then forward the render calls and split them
    up per row or whatever I finally decide on. I've also started thinking that iso layers (being view dependent) might benefit from
    not being derived from normal tile layers (or even scene objects) at all as we don't need to rotate them or apply physics to them,
    etc. Hmmm. Perhaps an t2dISOSceneGraph ;p Let's see what my trusty code rifle brings down then ;p

    Will keep you posted.

    [update 2006-04-04]

    I've updated the code for 1.1. but will only upload once I go over everything.

    [/update]

    ~neo
    Page «Previous 1 2
    #1
    07/30/2005 (4:09 pm)
    Please share!!
    Im about to start some iso code myself soon, and this would give me a good start :)
    #2
    07/30/2005 (4:18 pm)
    I'm doing some testing first to see if things break somewhere along the line, but
    will post stuff as soon as I can ;p

    ~neo
    #3
    07/30/2005 (4:21 pm)
    I was going to go about it the same way you were.
    ok ill wait.
    I give you a minute or 2! :)
    #4
    07/30/2005 (7:51 pm)
    Just a thought. If you would reposition a 2nd layer with it's origin shift half the tilewidth for both the X and Y... wouldn't give that exactly the same result?

    - Edo.
    #5
    07/30/2005 (8:51 pm)
    Yes it does, and I mentioned that as well,

    Quote:
    which you can fake with two overlapping layers with tiles in alternate positions:

    It just gets unwieldly tracking two layers for every "virtual" layer you want.
    I initially did it that way. I changed the editor code to allow offsetting a layer and link it to another layer, etc.
    However once I started piling on the layers it quickly became unmanageable and besides it didn't feel "right" to me
    I'm a bit of a purist when it comes to stuff like this I suppose. ;p

    This is more of a experiment for me to find the limitations (and possible improvements) for the T2D engine as
    well as getting my hands dirty with the underlying code.
    It starts quite simple and leads to other ideas like allowing tiles to scale outside of their cliprects in say -Y to
    allow for arbitrary "heights" of walls, etc, but generalized into discreet functionality that enhances the engine.

    Having a clean interface that takes care of all these things implicitely in code instead of having to fake it
    in script seems to me the best way to go.

    Obviously YMMV.

    ~neo
    #6
    07/30/2005 (11:30 pm)
    Yeah I see your point and agree. For this I'd proberly prefer the axis to be turned 45 degrees so that not even/uneven rows determine the interleaved tiles but rather have a logic xy system where the tile left up would be -1X and up right would be +1Y.
    #7
    07/31/2005 (12:52 pm)
    Very cool Neo! We tried to make the tile system as easy to extend and modify as possible (thinking specifically about ISO tiles), but there's definitely some work involved with it. Nice job, please keep us posted!

    Btw, you've been doing some really cool stuff already. Liked your Atlas terrain GUI too. :)
    #8
    08/01/2005 (12:20 pm)
    @Edo:
    Well these are just rendering coords... nothing really to do with how you define X,Y(and Z) coords in the "virtual" map. The tile map is then mapped to and from that coord system. I do agree that accessing the map that way (basically north is top right) is more
    intuitive and it is basically the "standard" way of doing things. I will play with some further ideas I have about this.
    Also something else to consider re: using overlapped layers (which I forgot to mention in my previous post) is that you get overlapped pick coords for each square tile, while my solution provides correct tile picking.

    @Josh:
    Thanks for the kind comments ;p
    #9
    08/01/2005 (5:02 pm)
    Hmmm... think it would be a good idea to draw the grid first so it stays at the right "depth" and allow
    the tiles to hide it; should give better depth perception etc.

    ~neo
    #10
    08/01/2005 (5:07 pm)
    Give it a try man!
    Gotta get my Animation Datablock Tool done, so i give your iso code a try!!!!
    Come on man, im like a lil kid waiting for Sponge Bob Square Pants to come on......
    :)
    #11
    08/01/2005 (5:14 pm)
    Hehehe, I still have to clean up a lot of stuff etc... will let you know soon as ;p

    ~neo
    #12
    08/01/2005 (5:23 pm)
    *whip whip
    Faster, faster! No food or sleep till the code is done!!!

    Its sweet that some of the T2D community is helping to fill in the uncompleted areas.
    Keep up the great work man!
    #13
    08/01/2005 (10:13 pm)
    @Neo Overlapped coords could also just be 'virtual'... hehe :) Anyway. It's looking good what you're doing there. It would be a nice addition to T2D and having it accessible with xyz coords and through an editor would greatly simplify things.
    #14
    08/03/2005 (1:21 am)
    Interested in this one, only reason I would get T2D would be if it had a iso engine, its the only style of 2d game I like :)
    #15
    08/09/2005 (11:15 pm)
    How is it going Neo? I'm willing to assist, if you need it.
    #16
    08/11/2005 (8:39 am)
    Been on holiday for a bit so haven't had time yet to look at it further.
    Back now so will update soon.

    ~neo
    #17
    08/17/2005 (10:39 am)
    Keep us updated Neo :)
    #18
    08/25/2005 (11:29 am)
    Pheew... back after another brief holiday ;p

    Will be getting back to this shortly and start sharing...

    Some issues with the underlying stuff (artifacts if grid is moved, etc) I still have to tackle
    as I don't want to post stuff I feel is not ready. Anyone interested though just pop me
    a mail and I'll send some of the stuff I'm working on for you to take a squiz at.

    ~neo
    #19
    08/26/2005 (10:57 am)
    Neo - I didn't see an email address for you. I'd like to take a peek even if its not totally ready. I bet others would too. Go ahead and post it as long as it builds and just give us a run down on what items are really, really busted. This can help start the feedback loop. I'm super interested in getting this working.

    Do you know if there are plans on putting ISO stuff into the T2D build?
    #20
    08/26/2005 (11:10 am)
    Hmmm... well I do believe in release soon and release often, so I'll just post the stuff with
    a big "Use at own risk and if this molests yer dog, it aint my fault, etc".

    And yes youre right its always good to get people throwing ideas around when they're
    all looking at the same thing.

    I will package it up and post it tomorrow (Sat) when i get a chance, and ego be damned ;p

    ~neo

    ps: are plans public and I should post a resource instead or post it in the private forums, how does it work?
    Page «Previous 1 2