私は、C++ と SDL を使用して設計してきたビデオ ゲームのタイル システムに取り組んできました。コードは、lazyfoo.net で利用可能なチュートリアルに大まかに基づいていますが、タイルを画面に描画するシステムが異なります。コードは次のように機能します。Map
という別のクラスの配列を作成する というクラスがありTile
ます。またset_tiles
、.map ファイルから数値を読み取り、tile
2 つの 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 );
}