Drawing Tilemaps Help

I've got this config file below that I am trying to load, however I am not finding a very concrete guide anywhere on it. I've tried simply using orxObject_CreateFromConfig, however nothing appears. Does anyone have any advice, or can tell me where in the config I've messed up?

[TileGraphicbeginning]
Texture    = "SnowSides.png"
Pivot  = top left
TextureSize    = (32,32,0)

[[email protected]]
TextureOrigin  = (0,0,0)

[[email protected]]
TextureOrigin  = (32,0,0)

[[email protected]]
TextureOrigin  = (64,0,0)

[[email protected]]
TextureOrigin  = (96,0,0)

[[email protected]phicbeginning]
TextureOrigin  = (128,0,0)

[[email protected]]
TextureOrigin  = (160,0,0)

[[email protected]]
TextureOrigin  = (192,0,0)

[[email protected]]
TextureOrigin  = (224,0,0)

[[email protected]]
TextureOrigin  = (256,0,0)

[[email protected]]
TextureOrigin  = (288,0,0)

[[email protected]]
TextureOrigin  = (0,32,0)

[[email protected]]
TextureOrigin  = (32,32,0)

[[email protected]]
TextureOrigin  = (64,32,0)

[[email protected]]
TextureOrigin  = (96,32,0)

[[email protected]]
TextureOrigin  = (128,32,0)

[[email protected]]
TextureOrigin  = (160,32,0)

[[email protected]]
TextureOrigin  = (192,32,0)

[[email protected]]
TextureOrigin  = (224,32,0)

[[email protected]]
TextureOrigin  = (256,32,0)

[[email protected]]
TextureOrigin  = (288,32,0)

[[email protected]]
TextureOrigin  = (0,64,0)

[[email protected]]
TextureOrigin  = (32,64,0)

[[email protected]]
TextureOrigin  = (64,64,0)

[[email protected]]
TextureOrigin  = (96,64,0)

[[email protected]]
TextureOrigin  = (128,64,0)

[[email protected]]
TextureOrigin  = (160,64,0)

[[email protected]]
TextureOrigin  = (192,64,0)

[[email protected]]
TextureOrigin  = (224,64,0)

[[email protected]]
TextureOrigin  = (256,64,0)

[[email protected]]
TextureOrigin  = (288,64,0)

[[email protected]]
TextureOrigin  = (0,96,0)

[[email protected]]
TextureOrigin  = (32,96,0)

[[email protected]]
TextureOrigin  = (64,96,0)

[[email protected]]
TextureOrigin  = (96,96,0)

[[email protected]]
TextureOrigin  = (128,96,0)

[[email protected]]
TextureOrigin  = (160,96,0)

[[email protected]]
TextureOrigin  = (192,96,0)

[[email protected]]
TextureOrigin  = (224,96,0)

[[email protected]]
TextureOrigin  = (256,96,0)

[[email protected]]
TextureOrigin  = (288,96,0)

[[email protected]]
TextureOrigin  = (0,128,0)

[[email protected]]
TextureOrigin  = (32,128,0)

[[email protected]]
TextureOrigin  = (64,128,0)

[[email protected]]
TextureOrigin  = (96,128,0)

[[email protected]]
TextureOrigin  = (128,128,0)

[[email protected]]
TextureOrigin  = (160,128,0)

[[email protected]]
TextureOrigin  = (192,128,0)

[[email protected]]
TextureOrigin  = (224,128,0)

[[email protected]]
TextureOrigin  = (256,128,0)

[[email protected]]
TextureOrigin  = (288,128,0)

[TilesMap]
Map    = beginning43 #beginning43 #beginning43 #beginning43 #beginning43 #beginning43 #beginning43 #beginning11 #beginning10 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 #beginning2 

Comments

  • Hi Sacked, you still need to create code to loop through and paint in place. There is a small guide here that should be able to help: https://wiki.orx-project.org/en/tutorials/community/sausage/semi-dynamic_objects_and_level_mapping

    Let me know if you have any issues with it.

  • edited May 18

    Thanks for the help. I did have a bit of a hard time understanding what the code was doing given how poor at programming I am so I added some comments to it, I'll post it in case it helps someone.

    bool PaintTiles(int tileIndexPosition){
    
        int mapLength = sizeof(map) / sizeof(map[0]);
            orxLOG("Length %d map[0] %d map %d", mapLength, sizeof(map[0]), sizeof(map)    );
        if (tileIndexPosition >= mapLength)
            return false;
    
        for (int x=0; x<TILES_ACROSS; x++){
            int i = x + tileIndexPosition;
    
            if (i > mapLength-1){
                return false; //out of tiles, no more drawing
            }
    
            //Create String in format: Tile{Number}, for example "tile8".
            orxCHAR buffer[6];
            orxString_Print(buffer, "tile%d", map[i]);
    
            //Create Tile{Number} object from config file, utilizing string created above.
            //Note our tiles are stored as "[[email protected]]" in our config file. 
            orxGRAPHIC *graphic;
            graphic = orxGraphic_CreateFromConfig(buffer);
    
            //Create Default Tile object, which holds our fullsize image.
            orxOBJECT *tile;
            tile = orxObject_CreateFromConfig("TilesObject");
    
            //Link our Tile{Number} config to our fullsize image.
            //The Tile{Number} config contains the portion of our fullsize tilemap image that we want to display.
            orxObject_LinkStructure(tile, orxSTRUCTURE(graphic));
    
            //Position our tile on the screen.
            orxVECTOR tilePos;
            tilePos.fX = (80 * x);
            tilePos.fY = 160;
            tilePos.fZ = 0;
            orxObject_SetPosition(tile, &tilePos);
    
        }
    
        return true;
    }
    
  • Oops I have some hard coded numbers in there instead of working out the tile positions from the width and height of a tile :) But it's ok for demonstration purposes.

    Good comments.

  • edited May 18

    Just a quick comment on that code, the following part is not safe:

            //Create String in format: Tile{Number}, for example "tile8".
            orxCHAR buffer[6];
            orxString_Print(buffer, "tile%d", map[i]);
    

    buffer can only hold tile + 1 single digit + string terminal character.
    If map[i] is > 9, this will result in a buffer overflow.

    A safer version would be, for example:

            //Create String in format: Tile{Number}, for example "tile8".
            orxCHAR buffer[16] = {};
            orxString_NPrint(buffer, sizeof(buffer) - 1, "tile%d", map[i]);
    
  • Fixed both in the wiki. Thanks guys.

  • Thanks!

  • edited May 22

    I was thinking of another way to do this, would there be a way to dynamically load objects based on proximity to an object? Perhaps adding an "existence" parameter that activates an object when they are N coordinates away from another object, perhaps tied to some sort of broadphase for collision detection?

    It could be useful in other areas as well, like dynamically loading levels as a player progresses.

  • You'd have to write your own system to handle world streaming. I'd recommend starting with something simple, maybe attached to a clock with a lower frequency. Such a system could be based on a regular grid with cells being object hierarchies that would be created/deleted based on the anchor(s) positions.

    I'd actually like to demonstrate such a system as you can see in my video sample todo list, Trello card at https://trello.com/c/ee9GBOlD/39-world-streaming.

    That being said, if you're only interested in rendering background tiles, I'd recommend using a shader-based approach where all the tile data is stored inside a texture and the rendering is entirely GPU-based. You can find an example at: https://github.com/iarwain/tilemap

  • I'm doing some testing to see what I can do, is there a max size for config file arrays?

    I've got 30k characters in a config file which make up a map, however its crashing with an error "No value for key <#24#25#26#27#28#29...". I dont see any reference to any maximum, and it seems like I can draw 40k tiles using random values, it seems to just be the config file.

  • There are indeed two limits.

    The first one is the size of the buffer we're using for streaming config content from file, which is 16kb, so a full key = value pair needs to fit inside that limit. One way to get passed that limit is to modify the content's of the config at runtime, using the orxConfig API. The buffer limit used there is 512kb.

    The second limit is the number of entries in a single config list: there's a maximum of 65535 entries per list.

    Regarding your map's storage, you have multiple options as well:

    • use a hierarchical approach, the map is an object which will have children for the subdivisions (you can have multiple levels of subdivisions as well
    • use a naming convention approach with separate sections, and iterate through them in code until you don't find anymore (a bit cumbersome)
    • separate the map in multiple data structures:
      • a tile index texture for rendering (using the shader-based approach mentioned earlier)
      • an object hierarchy for everything that will be moving and/or have a physical/animated presence
Sign In or Register to comment.