Dec 15, 2012

I completed my tile map scripts. They're not the same as those used in CV3 because, well, those ones were overly complicated. For example, horizontal stages wrote the tile map rotated counter-clockwise, meaning tiles on the bottom of the screen were written on the right of the map. Then there was the fact only 288 tiles were stored at any one time, whereas simply compiling an array at room start would be faster in the long run (although there was some noticeable delay on my laptop of about 2 seconds, but I was also writing to a binary file at the time).

I never really could find any documentation on how to write a tile map except some code for C++. Since none of that code resembled the mess of code in CV3, I ignored what little I could find. Eventually I realized I shouldn't have and just merged all the ideas into one set of scripts.

The first thing to do is compile a list of all the actual tiles in the room. Unfortunately, GM only provides the IDs of tiles, so we need to retrieve the coordinates of the tiles in the tile sheet and then use that as the basis for identifying our tiles.

var A,X,Y,temp_map,tile_width,tile_height;
temp_map[0] = 0;
A = 0;

tile_height = tile_layer_find(1000000,0,0);
tile_width = tile_get_width(tile_height);
tile_height = tile_get_height(tile_height);

for(Y=0; Y<room_height; Y+=tile_height)
for(X=0; X<room_width; X+=tile_width)
{
   temp_map[A] = (tile_get_left(tile_layer_find(1000000,X,Y))  

     div tile_width) | (tile_get_top (tile_layer_find(1000000,X,Y))
     div tile_height) << 4;
   A += 1;
}


We need to then take that array and run it through a tile definition script. This is simple enough.

for(X=0; X<A; X+=1)
{
    for (Y=0;Y<solid_count;Y+=1)
    if solid_map[i]>=0
    {
        if temp_map[X]>solid_map[Y]
            temp_map[X] =   solid_map[Y] mod 6;
    }
    else break;
}


The array solid_map in this example holds all the definitions. In this case, tile sheets would need to be arranged so that all tiles of the same type are together and located in the bottom-right section of the tile sheet. Of course there are other ways of defining solid tiles, but this was how CV3 did it.

Technically our tile map is finished by this point, but more than likely our solid definitions occupy a single nybble or less of data (in this example, it occupies 3 bits. We should therefore economize our tile map so it takes up even less memory. You'll notice everything up to this point has been defined by temporary variables (or the global array solid_map). The tile map itself will be a global array.

Y       =   0;
for(X=0; X<A/2; X+=1)
{
    tile_map[X] =   temp_map[Y]<<4|temp_map[Y+1];
    Y           +=  2;
}


That's all there is to writing a tile map via script. Believe it our not, that was the hard part. Reading the tile map is the easy part.

var i;
i   =   tile_map[(x>>5)*(room_height>>4)+(y>>4)];
if x+argument1 & $10
    return i & $0F;
else
    return i >> 4



And there you have it -- the basics of writing and reading a tile map. Some of the numbers might be a bit off because I didn't generalize the tile map reading script. This was based on a 16x16 metatile (the tile sheet can be comprised of any size tiles). Also, be sure the tile sheet does not exceed 16 tiles horizontally. Any height should be okay for the tile sheet. If you need to change that around, though, you should be able to just swap the order of tile_get_top and tile_get_left so that the tile's left coordinates get shifted 4 bits instead. You shouldn't ever need to use an entire word of data, but if you do just increase <<4 in the tile coordinate read for each extra bit you need.

No comments:

Post a Comment

©TheouAegis Productions™. Powered by Blogger.