# [.net] Parsing a TileSet [XNA sorta]

This topic is 3596 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I was wondering if I was parsing a tile set for the number of tiles in it was the easiest way of doing it. I didn't want to have an extra file laying around describing each tile set so I implemented this... Notes: * Tiles are 32x32 * tile_tilemap.GetTileFromID(numtiles) is a tile map class and will return a source rectangle (for XNA's SpriteBatch) depending on the ID given to it. * Comments were added for post
            bool done = false;            // Typical are we done flag
Color[] c = new Color[1024];  // Array of colors to hold each tile
do
{
// Get the Rect of the current tile
Rectangle tile = tile_tilemap.GetTileFromID(numtiles);
// Get the data of the tile
tile_tilemap.Tex.GetData<Color>(0,tile,c,0,1024);
done = true;
for (int y = 0; y < 32; y++)
for (int x = 0; x < 32; x++)
{
// Here, go through each pixel of the tile.
// We check for a color other than
// nothing (0r,0b,0g,0a)
if (c[y*x] != new Color(0,0,0,0)) done = false;
}
// if done==false then a color (other than nothing) was
// found, inc number of tiles
if (!done) numtiles++;

// wash rinse repeat
} while (!done);


Now the above works great. But there is only 4 tiles in a 1024x1024 tileset for now. My concern, once I decided to doodle some more tiles, is this will take a while if the texture is full of tiles (1024 of 'em) and checking each and every pixel (1,048,576 of those) and multiple tile sets. Loading is done at the beginning and never again. I know I can just make a simple text file with the number of tiles, but I'd rather not have to worry about updating the file each time I add new tiles. Any suggestions? As a side question, I was wondering, is it safe to assume if a graphics card is capable of running XNA, then it would be able to use larger than 1024x1024 textures?

##### Share on other sites
I don't see why it matters if you add a bunch of blank tiles. As long as their ID's aren't referenced in the map, they won't show up, so having a few extra tiles won't hurt anything. If you ignore the blank tiles, you will be able to speed up your algorithm quite a bit. In short, you should just assume that every tile in a texture contains useful data.

##### Share on other sites
That would actually work for me, but how would I know if the user clicked on a valid tile? Right now, only the valid tiles are drawn. If I used your advice (and probably will), how would I validate the tile? I'm sure the user would realize they are drawing blank tiles, but we all know sometimes, end-users are not that bright.

Edit: Ok, never mind. The more I think about it, its the simplest route to take. If the user can't figure it out, then oh well, they will have holes in their map.

##### Share on other sites
Actually, I will stick with the way I was doing it. Thanks for the help though. I got it to load much faster. Basically, if it finds a pixel that is colored, then it stops checking the rest of the tile and moves along to the next tile. Only down side I see with this is, if the tile data is in the lower right hand side of the tile, it has to check everything down to it. But I don't see that happening to often for me.

Code for others if they are curious.
Oh yeah, I didn't mention this before but tile_tilemap.Tex is a Texture2D. The GetData from the Texture2D class.

            bool done = false;            Color[] c = new Color[1024];            Rectangle tile;            do            {                tile = tile_tilemap.GetTileFromID(numtiles);                                tile_tilemap.Tex.GetData<Color>(0,tile,c,0,1024);                done = true;                for (int y = 0; y < 32; y++)                {                    for (int x = 0; x < 32; x++)                    {                        if (c[y * x] != new Color(0, 0, 0, 0))                        {                            done = false;                            break;                        }                    }                    if (!done)                    {                        numtiles++;                        break;                    }                }            } while (!done);