Proper way to approach tiling?

edited September 2010 in Help request
Hi Guys, first post and I've gone as far as I can without help. Firstly, huge thank you to iarwain for a great engine which appears to be just right for what I want to do.

I have been experimenting with various techniques in readiness to start on my game and I'm stuck with tiling. I can tile an object using repeat/scale no problems, however:

I have a large PNG file containing a grid of tiles. Each of my tiles is 32 x 48 pixels and each containing a different type of tile.

My game are will be 640 x 48 so I will choose from the array of tiles and display them. My character runs across the screen and the tiles are re-painted and the character re-positioned at the start of the screen again (going form screen to screen - no scrolling).

My problem is, I have 110 different tiles. I want to choose the right tile and generate them dynamically rather than have to define each of the 110 tiles in the ini file.

In semi-pseudo code, I want to do this for one screen to paint it:
game.ini
========
[AllTilesGraphic]
Texture = "../../data/scenery/tileset.png" 

Code
====

//tiles across screen
int tileArray[] = { 01, 01, 01, 20, 01, 01, 88, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01 }; 

for (x=0; x<tileArray.length(); x++){
    orxVECTOR tileMapVector; //vector to get the tile from the map
    tileMapVector	.fX, fY, fZ = <Some maths to calc on the map sheet> 

    orxGRAPHIC *tile;
    tile = orxGraphic_Create();

    SomehowAssociateWithTextureGraphic(&tile, "AllTilesGraphic");
    SomehowMapTileFromGraphic(&tile, tileMapVector);

    orxOBJECT *tileObject;
    tileObject = orxGraphic_Create();

    SomehowAssociateWithGraphicObject(tileObject, tile);
    orxObject_SetPosition(tileObject, <some vector along the screen>);
}

Am I thinking correctly about this? Any advice would be very appreciated.

Thanks,
Wayne

Comments

  • edited September 2010
    sausage wrote:
    Hi Guys, first post and I've gone as far as I can without help. Firstly, huge thank you to iarwain for a great engine which appears to be just right for what I want to do.

    Hi Wayne, and welcome among us. =)
    I have been experimenting with various techniques in readiness to start on my game and I'm stuck with tiling. I can tile an object using repeat/scale no problems, however:

    I have a large PNG file containing a grid of tiles. Each of my tiles is 32 x 48 pixels and each containing a different type of tile.

    My game are will be 640 x 48 so I will choose from the array of tiles and display them. My character runs across the screen and the tiles are re-painted and the character re-positioned at the start of the screen again (going form screen to screen - no scrolling).

    My problem is, I have 110 different tiles. I want to choose the right tile and generate them dynamically rather than have to define each of the 110 tiles in the ini file.

    So, if I understand correctly, you have 110 different tiles of 32x48 stored in a single PNG but you don't want to define them all in a config file (which I totally understand as it would be extremely tedious).

    What I would do if I were you is write a simple orx program to generate that config file for you. :)

    Something like:
    orxVECTOR v;
    orxConfig_PushSection("TileBase");
    orxConfig_SetString("Texture", "MyTexture.png");
    orxConfig_SetVector("TextureSize", orxVector_Set(&v, 32.0f, 48.0f, 0.0f));
    orxConfig_SetString("Pivot", "top left");
    // Do the same for any common properties of your tiles' graphics.
    
    for(orxU32 i = 0; i < u32TileNumber; i++)
    {
      orxCHAR acBuffer[32];
      orxString_Print(acBuffer, "Tile%3ld", i);
      orxConfig_PushSection(acBuffer);
      orxConfig_SetParent(acBuffer, "TileBase");
    
      // Update your texture corner position in V
      v.fX = ...;
      v.fY = ...;
      orxConfig_SetVector("TextureCorner", &v);
    }
    
    // Let's save it
    orxConfig_Save("Tile.ini", orxFALSE, orxNULL);
    

    This way you can still use config-driven graphics but you skip the tedious part. Of course you can do this init at the beginning of the game, every time it's launched, and not store it in a config file. The config data would still be in memory and useable by the _CreateFromConfig() functions.

    Now, how do you plan on defining your screens? If I read correctly your pseudo code below, you'd have an array of tiles for each screen?

    I'd suggest to save them as a list in screen sections. And you could also easily bind the screens through config.

    A small example:
    
    [Game]
    ScreenList = Screen1 # Screen2 # Screen3 # ...
    
    [Screen1]
    Left = Screen2
    Up = Screen3
    TileList = Tile003 # Tile006 # ...
    
    [Screen2]
    Right = Screen1
    Left = Screen2 ; <= Looping here, as it's sometimes done in "labyrinthic" games
    TileList = ...
    
    [Screen3]
    ...
    
    

    Of course, those data (especially the TileList property) can also be generated by code and not written manually in the config file. This allows easy randomization for example.

    The config system is more than just input parameters for orx's structures. It's an all purpose weakly-typed storage system that can be updated at runtime. If you look at the small game I wrote at the beginning of the year called MushroomStew, you'd see I use it to store temporary status for objects, such as flagging which object is currently slowed down or under the gravity gun influence.
    In semi-pseudo code, I want to do this for one screen to paint it:
    game.ini
    ========
    [AllTilesGraphic]
    Texture = "../../data/scenery/tileset.png" 
    
    Code
    ====
    
    //tiles across screen
    int tileArray[] = { 01, 01, 01, 20, 01, 01, 88, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01 }; 
    
    for (x=0; x<tileArray.length(); x++){
        orxVECTOR tileMapVector; //vector to get the tile from the map
        tileMapVector	.fX, fY, fZ = <Some maths to calc on the map sheet> 
    
        orxGRAPHIC *tile;
        tile = orxGraphic_Create();
    
        SomehowAssociateWithTextureGraphic(&tile, "AllTilesGraphic");
        SomehowMapTileFromGraphic(&tile, tileMapVector);
    
        orxOBJECT *tileObject;
        tileObject = orxGraphic_Create();
    
        SomehowAssociateWithGraphicObject(tileObject, tile);
        orxObject_SetPosition(tileObject, <some vector along the screen>);
    }
    

    Am I thinking correctly about this? Any advice would be very appreciated.

    Thanks,
    Wayne

    Your pseudo-code sounds good to me. I'd use more the config system again, especially for the tiles to load. Probably something like:
    INI:
    
    [TileObject]
    Here you can put any common property for your tile objects, such as a fade in FX for example
    
    CODE:
    
    orxConfig_PushSection(zCurrentScene);
    
    for(orxU32 i = 0; i < orxConfig_GetListCounter("TileList"); i++)
    {
      orxVECTOR v;
      // Let's update the TileObject graphic property with the one from the current screen
      orxSTRING zTile = orxConfig_GetListString("TileList", i);
      orxConfig_PushSection("TileObject");
      orxConfig_SetString("Graphic", zTile);
      v.fX = ...;
      v.fY = ...;
      v.fZ = ...;
      orxConfig_SetVector("Position", &v);
      orxConfig_PopSection();
    
      // Now we simply need to create the TileObject that will have the correct tile graphic and position
      orxObject_CreateFromConfig("TileObject");
    }
    

    It's a very basic scheme but I think it's a good base. You can add a lot of subtleties on top of it. Such as having fade in FX started with an initial delay depending on the value of i and get a nice effect.
    When you need to delete your current screen, simply crawl through all the orxOBJECT using orxSTRUCTURE_GetFirst/GetNext and updated the object's life time if its name matches TileObject, or, better, put a IsTileObject = true as config property and check it with orxConfig_GetBool("IsTileObject").

    Hope this helps! If it's too confusing, let me know but I might not be able to reply for a couple of days as I begin to move tomorrow from Canada to USA.

    - iarwain
  • edited September 2010
    Thanks, iarwain!
  • edited September 2010
    My pleasure! =)

    You edited your second post before I could reply but I guess that my post answered some of your problems? Let me know if there are still any dark spots.

    Don't hesitate to ask whenever you have questions, I'm sure you'll get answers from other boarders within a reasonable delay. :)
  • edited September 2010
    Yes I did sorry. I was inserting a chart to explain it further and we cross-posted so I edited my post to suit. Most of what you explained certainly helps but I need to dig a little through your MushroomStew game, as I have more questions as a result. :)

    However, you have a move coming up, so I'll spend some time educating myself and post back hopefully by the time you're moved and settled. All the best with it!
  • edited September 2010
    Don't hesitate if you have any questions, at worst I'll be able to reply on wednesday.

    But since then I'm sure I'll have some WIFI connection in airports or at some friends' place. :)

    I often overlook things when giving advises as I'm too much used to orx.
    Don't hesitate to ask for more details/explanations if things I wrote remained obscure.
Sign In or Register to comment.