Re: A89: Tile-based Game Engine in C


[Prev][Next][Index][Thread]

Re: A89: Tile-based Game Engine in C




Sorry, the last copy of this message was cut off an incomplete:
----------------------------

> in C would it be something similar to:
> int sometile1[] = { 0x...};
> char tilearray[] = {&sometile1,...};

That could use a little of refinement, since the second array's type is
completely wrong. . .

First, each sprite must be defined.  The exact declaration will vary
depending on the sprite format and blitting (drawing) routine you use.  For
simplicity's sake, let's assume you're using Zeljko's nice TIGCCLIB sprite
specifications, and you're using 16x16 sprites.

The format for defining sprite data is covered by TIGCCLIB.

You then need an array indexing all of the sprites.  This should be an array
of type pointer to (sprite type).  Since a 16x16 TIGCCLIB sprite is of type
pointer to int (it's an array, so it's a pointer), our array would look like
this:

int** tile_array[] = {&tile_zero_name, &tile_two_name, ... };
/* you sould, of course, use your own sprite names above    */

For simplicity's sake, I suggest the doing following:
typedef int* sprite;
sprite* tile_array[] = {&tile_zero_name, &tile_two_name, ... };

The most basic map format will assume that every map is the same size and
consist of a simple two-dimensional array of ints, with each number
representing the tile of that index in tile_array.  If we had a 10x10 map,
it might look like this:

int map_data[][] =
 {
    {1,1,1,1,1,1,1,1,1,1},
    {1,3,3,3,3,3,3,3,3,1},
    {1,3,5,4,4,4,4,5,3,1},
    {1,3,5,4,4,4,4,5,3,1},
    {1,3,5,5,5,5,5,5,3,1},
    {1,3,0,0,0,0,0,0,3,1},
    {1,3,0,0,2,2,0,0,3,1},
    {1,3,0,0,2,2,0,0,3,1},
    {1,3,3,3,2,2,3,3,3,1},
    {1,1,1,1,2,2,1,1,1,1}
 };

I'll leave the map drawing routine up to you, but it's pretty
straightforward: one "for" loop nested inside another.

If we only have 256 or fewer tiles, then we're wasting a ridiculous amount
of space using ints.  If you understand the calculator's workings at an
assembly-language level (which is pretty important if you want to achieve
efficiency on such a low-level device), you'll realize that we simply want
to use a byte, which is, in C, an unsigned char.  Try this slight
improvement:

typedef unsigned char BYTE;
BYTE map_data[][] =
 {
    {1,1,1,1,1,1,1,1,1,1},
    {1,3,3,3,3,3,3,3,3,1},
    {1,3,5,4,4,4,4,5,3,1},
    {1,3,5,4,4,4,4,5,3,1},
    {1,3,5,5,5,5,5,5,3,1},
    {1,3,0,0,0,0,0,0,3,1},
    {1,3,0,0,2,2,0,0,3,1},
    {1,3,0,0,2,2,0,0,3,1},
    {1,3,3,3,2,2,3,3,3,1},
    {1,1,1,1,2,2,1,1,1,1}
 };

When you start doing things like this, it may be smart to typecast the value
to an unsigned int before using it as an array index.

If you want to make the map of variable size, try this:

struct map
 {
    unsigned int width;
    unsigned int height;
    BYTE* data[][];
 };

Note that it contains a _pointer_ to the data, and not the data itself.
This is because of what is, IMHO, one of C's major fallacies - ANSI C does
not allow for structs to contain arrays whose size is not always the same.
Our data is of size width*height, but since width and height vary, we would
_want_ our array to look like this:





References: