2013-02-17 85 views
0

我一直在爲我一直在通過C++和SDL設計的視頻遊戲開發平鋪系統。該代碼鬆散地基於lazyfoo.net上提供的教程,但使用不同的系統將圖塊繪製到屏幕上。代碼的工作原理如下:我有一個名爲Map的類,它創建了另一個類Tile的數組。它還有一個叫set_tiles的函數,它讀取.map文件中的數字,並使用兩個for循環將它們複製到tile的數組中;一個用於x的,另一個用於y的。然後,根據Tile的特定變量,將每個表面都映射到臨時映射。下面是實際的代碼:平鋪系統C++ SDL

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; 
} 

}

的問題是,set_tiles返回NULL指針時它被稱爲。通過一些調試,我發現它一直到最後,然後返回一個NULL,但它不會在for循環中的某處執行。我也嘗試將所有tile crop.x's和y's設置爲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); 

}

+0

定義了什麼'Setup'類?除非'apply_surface'函數將SDL_Surface指針作爲第四個參數(即'SDL_Surface *&')引用,否則此函數中沒有任何內容將temp_map從其初始化更改爲NULL指針。 – 2013-02-17 05:12:27

+0

谷歌搜索「apply_surface」將我引向[this](http://lazyfoo.net/SDL_tutorials/lesson06/index.php),但在這種情況下,它不是一個類的成員。如果這是你從中獲取代碼的地方,並且只是將它封裝在一個名爲'Setup'的類中而不改變參數類型,那麼是的,你在調用'apply_surface'時犯了一個錯誤。 – 2013-02-17 05:17:43

+0

好Google fu - 我刪除了我的答案。我錯誤地假設了一些東西。 – 2013-02-17 05:23:15

回答

1

SDL_BlitSurface的blit一個表面到另一個表面。它們都必須被初始化,否則該函數什麼都不做。你傳遞一個NULL指針給它。你需要通過調用SDL_CreateRGBSurface來初始化指針。

+0

這很有道理。我做了一些研究,並發現如何使用'SDL_CreateRGBSurface'。它不再返回NULL。但是,它仍然沒有返回我想要的圖像。某處還有其他問題。 – 2013-02-17 06:02:22

+0

@JimHurley:我不懷疑,但每個帖子都有一個問題。 – 2013-02-17 06:05:29

+1

是的,先生。我會自己處理一段時間。 – 2013-02-17 06:09:18