James Hurley
James Hurley

Reputation: 762

Tiling System C++ SDL

I have been working on a tiling system for a video game I've been designing through C++ and SDL. The code is loosely based off of the tutorials available on lazyfoo.net, but with a different system to draw the tiles to the screen. The code works as follows: I have a class called Map that creates an array of another class called Tile. It also has a function called set_tiles that reads numbers from a .map file and copies them to the array of tile's using two for loops; one for the x's and one for the y's. I then blit each surface to a temporary map according to the Tile's specific variables. Here is the actual code:

Map.cpp

SDL_Surface* Map::set_tiles ( SDL_Surface* tile_image ) {
Setup setup;

SDL_Surface* temp_map = NULL;

//Open the map
std::ifstream map ( "Test.map" );

//Catch any errors
if ( map.fail() ) return NULL;

//Initialize the tiles
for ( int y = 0; y < MAP_HEIGHT / TILE_HEIGHT; y++ ) {
    for ( int x = 0; x < MAP_WIDTH / TILE_WIDTH; x++ ) {
        //Determines the tile type
        int tile_type = -1;

        //Read the tile type from the map
        map >> tile_type;

        //Make sure it's a real tile
        if ( tile_type < 0 || tile_type >= TILE_SPRITES ) {
            map.close();
            return NULL;
        }

        //Error check for the .map file
        if ( map.fail() ) {
            map.close();
            return NULL;
        }

        //Add the tile to the array
        tile_array[x][y] = &Tile ( x, y, tile_type );

        //Create the temp. image crop
        SDL_Rect* temp_crop = &tile_array[x][y]->get_crop();

        //Check for crop errors
        if ( ( temp_crop->h || temp_crop->w ) == 0 ) return NULL;

        //Edit the temp. map
        setup.apply_surface ( x * TILE_WIDTH, y * TILE_HEIGHT, tile_image, temp_map, temp_crop );
    }
}

map.close();

//Return the modified map
return temp_map;

}

Tile.cpp

Tile::Tile ( int x, int y, int tile_type ) {
//Get the offsets
box.x = x;
box.y = y;

//Set the collision box
box.w = TILE_WIDTH;
box.h = TILE_HEIGHT;

//Get the tile type
type = tile_type;

//Choose the crop option
crop.w = TILE_WIDTH;
crop.h = TILE_HEIGHT;

switch ( tile_type ) {
case TILE_RED:
    crop.x = 0 * TILE_WIDTH;
    crop.y = 0 * TILE_HEIGHT;
    break;
case TILE_GREEN:
    crop.x = 1 * TILE_WIDTH;
    crop.y = 0 * TILE_HEIGHT;
    break;
case TILE_BLUE:
    crop.x = 2 * TILE_WIDTH;
    crop.y = 0 * TILE_HEIGHT;
    break;
case TILE_CENTER:
    crop.x = 3 * TILE_WIDTH;
    crop.y = 0 * TILE_HEIGHT;
    break;
case TILE_TOP:
    crop.x = 0 * TILE_WIDTH;
    crop.y = 1 * TILE_HEIGHT;
    break;
case TILE_TOPRIGHT:
    crop.x = 1 * TILE_WIDTH;
    crop.y = 1 * TILE_HEIGHT;
    break;
case TILE_RIGHT:
    crop.x = 2 * TILE_WIDTH;
    crop.y = 1 * TILE_HEIGHT;
    break;
case TILE_BOTTOMRIGHT:
    crop.x = 3 * TILE_WIDTH;
    crop.y = 1 * TILE_HEIGHT;
    break;
case TILE_BOTTOM:
    crop.x = 0 * TILE_WIDTH;
    crop.y = 2 * TILE_HEIGHT;
    break;
case TILE_BOTTOMLEFT:
    crop.x = 1 * TILE_WIDTH;
    crop.y = 2 * TILE_HEIGHT;
    break;
case TILE_LEFT:
    crop.x = 2 * TILE_WIDTH;
    crop.y = 2 * TILE_HEIGHT;
    break;
case TILE_TOPLEFT:
    crop.x = 3 * TILE_WIDTH;
    crop.y = 2 * TILE_HEIGHT;
    break;
}

}

The problem is that set_tiles returns a NULL pointer when it is called. Through a bit of debugging I found that it makes it all the way to the end and then returns a NULL, it doesn't do it somewhere in the for loops. I've also tried setting all tile crop.x's and y's to 0, just to see if it would work, but it doesn't.

NOTICE The problem is not my image or the .map file. I think that my understanding of pointers may be a bit faulty, and that I may have made a mistake when calling apply_surface.

Setup.cpp

void Setup::apply_surface ( int x, int y, SDL_Surface* source, SDL_Surface* &destination, SDL_Rect* clip ) {
//Temporary rectangle to hold the offsets
SDL_Rect offset;

//Get the offsets
offset.x = x;
offset.y = y;

//Blit the surface
SDL_BlitSurface ( source, clip, destination, &offset );

}

Upvotes: 0

Views: 2578

Answers (1)

Benjamin Lindley
Benjamin Lindley

Reputation: 103733

SDL_BlitSurface blits one surface to another. They both must be initialized, otherwise the function does nothing. You are passing a NULL pointer to it. You need to initialize the pointer with a call to something like SDL_CreateRGBSurface.

Upvotes: 1

Related Questions