我一直在为我一直在通过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
时可能犯了一个错误。
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);
}
定义了什么'Setup'类?除非'apply_surface'函数将SDL_Surface指针作为第四个参数(即'SDL_Surface *&')引用,否则此函数中没有任何内容将temp_map从其初始化更改为NULL指针。 – 2013-02-17 05:12:27
谷歌搜索“apply_surface”将我引向[this](http://lazyfoo.net/SDL_tutorials/lesson06/index.php),但在这种情况下,它不是一个类的成员。如果这是你从中获取代码的地方,并且只是将它封装在一个名为'Setup'的类中而不改变参数类型,那么是的,你在调用'apply_surface'时犯了一个错误。 – 2013-02-17 05:17:43
好Google fu - 我删除了我的答案。我错误地假设了一些东西。 – 2013-02-17 05:23:15