0

私は、C++ と SDL を使用して設計してきたビデオ ゲームのタイル システムに取り組んできました。コードは、lazyfoo.net で利用可能なチュートリアルに大まかに基づいていますが、タイルを画面に描画するシステムが異なります。コードは次のように機能します。Mapという別のクラスの配列を作成する というクラスがありTileます。またset_tiles、.map ファイルから数値を読み取り、tile2 つの for ループを使用して の配列にコピーするという関数もあります。1 つは x 用、もう 1 つは y 用です。Tile次に、の特定の変数に従って、各サーフェスを一時的なマップにブリットします。実際のコードは次のとおりです。

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;

}

タイル.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;
}

}

問題は、set_tiles呼び出されたときに NULL ポインターを返すことです。少しデバッグしたところ、最後まで実行されてからNULLが返されることがわかりました.forループのどこかでそれを行いません。また、すべてtileのcrop.xとyを0に設定して、機能するかどうかを確認しましたが、機能しません。

注意 問題は私の画像や .map ファイルではありません。ポインターの理解が少し間違っている可能性があり、呼び出し時に間違った可能性があると思います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 );

}

4

1 に答える 1

1

SDL_BlitSurfaceある表面を別の表面にブリットします。両方とも初期化する必要があります。そうしないと、関数は何もしません。あなたはそれにNULLポインタを渡しています。SDL_CreateRGBSurfaceのようなものを呼び出してポインタを初期化する必要があります。

于 2013-02-17T05:45:21.540 に答える