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«First 1 2 Next»
    #21
    08/29/2005 (8:22 am)
    Best place would be to post it either in the private forums or in a new resource :) If you post it in a resource you can link us to the resource before it comes out as well... this resource would be very much appreciated
    #22
    08/29/2005 (8:53 am)
    I get ya... from what I've seen resources can't be assigned to a specific private context (e.g. tse only).
    Can they?

    I'd like to do it the best practice way if anyone can steer me in the right direction ;p

    ~neo
    #23
    08/29/2005 (8:59 am)
    They can, when GG approves the resource they can restrict it :) If you post the link ahead of time post it in the private resources, I don't think they are restricted before they get approved
    #24
    08/29/2005 (5:51 pm)
    Resource posted... will post a link as soon as it has been approved...

    ~neo
    #25
    09/01/2005 (12:53 pm)
    Urp... looks like my resource submission got swallowed... still can't see it or heard anything about it...

    strange...

    Resubmitted it, you can find it here

    ~neo
    #26
    09/01/2005 (7:27 pm)
    That gets redirected to the home page.
    #27
    09/02/2005 (4:30 am)
    Yes it does that if it has not been approved yet.

    I've posted it on the private forums in the mean time.

    ~neo
    #28
    09/03/2005 (1:47 am)
    @Neo: all your [ URL ] 's are broken.

    the reason: you surround your URL with quotes. dont do that. ex:

    [ur|=www.yahoo.com]do you yahoo[/ur|]

    NOT:
    [ur|="www.yahoo.com"]this doesnt work[/ur|]
    #29
    09/03/2005 (4:04 am)
    Ermm... nope... those urls are fine ... no quotes... (I learnt the hard way ;).

    They will not work if A) You don't have access to a forum or B) the resource has not been approved yet.

    Or I'm seeing a totally different site than everybody else ;p

    [edit]
    Ok I missed one... thought I had changed it... or something... spooky...
    [/edit]

    ~neo
    #30
    10/17/2005 (8:31 pm)
    @neo

    I thank you at first, that you provide the package.
    I have some questions about it's usage:

    (1) I modified the project following your direction. I can edit the isometric tilemap. But I cannot display the same tilemap when I close the T2D program and open it again.

    (2)Do you need to extend the class of "nxIsoTileMap", functions for "loadTileMap(...),saveTileMap(...)" to realize the isometric effect.

    (3)I use the class following this:
    %map = new nxIsoTileMap(){ scenegraph = t2dSceneGraph };
    But I failed to draw the isometric tilemap.

    Can you try it again follwing my questions ?
    Please give me a help, thanks a lot.
    #31
    10/18/2005 (5:51 am)
    Hi there, yeah I did not get to saving and loading as it was just the display part that I was experimenting with.

    The way to go would be to override the streaming and write a header or flag to say that it is an iso map and then
    let super class stream as usual. I wanted to wait until the new T2D file formats was released before getting into it.

    Just remember that this is not so much a "package" as basic code to show how one could display iso maps, and as such
    the onus is on each developer to use it as a base or learning tool and extend it.

    A quick fix to display loaded iso tile maps on default load:

    set $loadIsoMap = true on about line 16 of editorScreen.cs in the /tileeditor directory

    note that this will always use the nxIsoTileMap even when loading non-iso maps.

    When loading an iso tile map remember to make sure "isometric" checkbox is checked so that is knows to create an
    nxIsoTileMap instead of fxTileMap.

    as for 3) here is an example from the editor script:

    $editorTileMap = new nxIsoTileMap() { scenegraph = tileEditorSceneGraph2D; };

    so looks ok to me, are you calling loadTileMap() on the object etc?


    ~neo
    #32
    10/18/2005 (7:54 am)
    @Neo

    I edit the ISO tilemap again following with your viewpoint.
    I list my "editorScreen.cs" file as : www.bihua360.com/t2d/editorScreen.cs

    Step 1:
    I edit the tilemap, the picture as:
    www.bihua360.com/t2d/iso1018_001.jpg
    It looks very well.

    When I close the current tilemap file. I load it again from the current T2D program, the picture as:
    www.bihua360.com/t2d/iso1018_002.jpg

    In the progress, I donnot modify the "editorScreen.cs" file.

    Why not ?
    What can I do for it?

    Thanks.
    #33
    10/18/2005 (10:31 am)
    ah... sorry about that... looked in the source for fxTileMap::loadStream() and it does not call createTileLayer() whichs is overidden in nxIsoTileMap it creates the layers by directly calling new fxTileLayer.

    I will have a look at it and update the resource...

    ~neo
    #34
    10/18/2005 (11:10 am)
    Ok, updated it and it loads maps fine now

    Redownload the resource and recompile and you will be in bussiness ;p

    ~neo
    #35
    10/18/2005 (6:26 pm)
    @Neo

    Ok, it's ok. You are wonderful. lol
    Usage:
    Quote:
    $mapLayer = new ScriptObject();

    $mapLayer.map = new nxIsoTileMap() { scenegraph = t2dSceneGraph; };
    $mapLayer.map.loadTileMap( "~/client/maps/test_iso1018.map" );
    $mapLayer.tileLayer = $mapLayer.map.getTileLayer( 0 );
    $mapLayer.tileLayer.setTileSize( "32 32" );
    $mapLayer.tileLayer.setPosition( "0 0" );
    $mapLayer.tileLayer.setLayer( 31 );
    $mapLayer.tileLayer.setGroup( 31 );

    It can be showed in the running of T2D project. But the tilemap's moving, collision, shielding etc... have some matter. I will research the codes, please give me a suggestion or a help. Thanks a lot.

    My aim is to make an ISO rpg game using the T2D engine. Thanks.

    ~HugeOne
    #36
    10/26/2005 (6:54 am)
    @Neo

    About the effect:
    www.bihua360.com/t2d/effect.jpg
    I want to know how to define the data struction, using the class "fxImageMapDatablock2D".
    And then the how edit the tile object.
    www.bihua360.com/t2d/object.jpg
    When we edit the tilemap, the tile's placement can have a height view. How to get the effect ?
    Thanks you in advance..

    ~ HugeOne
    #37
    10/30/2005 (1:02 am)
    @Neo

    When I use the tilemap using the isometric mode, it will show in the running T2D an isometric game map. But when I scroll the tilemap, the tilemap will have some jags in the process of moving.

    It may be draw the tile when its half exceeds the edge. lol

    An other question:
    A sprite in the tilemap, can move around. Now ,how to shield each other with the other sprites, other bricks or objects etc.
    Can you tell me how to do it?

    Thanks.
    #38
    02/07/2006 (9:43 pm)
    Continue to doing it ...

    support it.
    Page«First 1 2 Next»