我正在尝试使用 SDL 编写游戏,但我遇到了很多奇怪的段错误。
我创建了类 Monster 和 Player,它们从类 Creature 中获取公共变量。类 Creature 从类 Object 中获取变量。就像这样:
class Object {
public:
Area* area_pointer; // Pointer to an Area in which object is present.
Sprite sprite; // Class that has SDL_Surface* and some other things.
Animation animation; // nothing usefull
int ID;
short int position_x; // nothing usefull
short int position_y; // nothing usefull
short int effect_x; // nothing usefull
short int effect_y; // nothing usefull
.... //Some functions that are not important right now.
};
类精灵:
class Sprite {
public:
SDL_Surface* image;
short int x;
short int y;
short int w;
short int h;
Sprite ()
{
image = NULL;
x = 0;
y = 0;
w = 0;
h = 0;
}
};
类生物,玩家,怪物:
class Creature : public Object {
public:
char move_direction;
char speed;
..// Some not important functions.
};
class Player : public Creature {
public:
char select_type;
int select_ID;
std::vector <Item> equip;
std::vector <Item> inventory;
std::vector <Effect> effects;
Player (Area* c_area_pointer, int data [])
{
area_pointer = c_area_pointer;
sprite.image = SurfaceLoad ("Images/Players/" + IntToString (data [0]) + ".png");
sprite.x = 0;
sprite.y = 0;
sprite.w = 0;
sprite.h = 0;
ID = data [0];
position_x = data [1];
position_y = data [2];
effect_x = 0;
effect_y = 0;
}
~Player ()
{
SDL_FreeSurface (sprite.image);
.....
}
};
class Monster : public Creature {
public:
char type;
std::vector <Item> loot;
std::vector <Effect> effects;
Monster (Area* c_area_pointer, int data [])
{
area_pointer = c_area_pointer;
sprite.image = SurfaceLoad ("Images/Monsters/" + IntToString (data [3]) + ".png");
sprite.x = 0;
sprite.y = 0;
sprite.w = 0;
sprite.h = 0;
ID = data [0];
position_x = data [1];
position_y = data [2];
effect_x = 0;
effect_y = 0;
type = data [3];
}
~Monster ()
{
SDL_FreeSurface (sprite.image);
.....
}
};
表面加载功能:
SDL_Surface* SurfaceLoad (std::string file_name)
{
SDL_Surface* surface_1 = NULL;
SDL_Surface* surface_2 = NULL;
surface_1 = IMG_Load (file_name.c_str ());
surface_2 = SDL_DisplayFormat (surface_1);
if (surface_1 != surface_2) SDL_FreeSurface (surface_1); // This line may be strange to some of you, but it is related to other error i had in past.
SDL_SetColorKey (surface_2, SDL_SRCCOLORKEY, 0xFFFFFF);
return surface_2;
}
我尝试从 txt 文件加载数据并基于它制作对象。我使用我自己的 Load 函数。它创建一个指向类对象的指针,例如:
Player* player;
std::string players_name = save_name + "Areas/" + IntToString (ID) + "/players.txt"; //Path to the file cointaining players data.
std::ifstream players_file;
players_file.open (players_name.c_str ());
Monster* monster;
std::string monsters_name = save_name + "Areas/" + IntToString (ID) + "/monsters.txt"; //Path to the file cointaining monsters data.
std::ifstream monsters_file;
monsters_file.open (monsters_name.c_str ());
然后它从文本文件中加载数据并将其放入名为 file_data 的 int 数组中,并基于它创建新的类对象。
while (!players_file.eof ())
{
getline (players_file, file_text);
while (file_text [data_position_2 + 1] != ';')
{
data_position_2 = file_text.find (",", data_position);
data.assign (file_text, data_position, data_position_2 - data_position);
file_data [data_index] = atoi (data.c_str ());
data_position = data_position_2 + 1;
data_index++;
}
player = new Player (this, file_data);
this->area_map.players.push_back (*player); //Vector players inside object area_map which contain also monsters vector. "this" is a pointer to object that contain Load function and area_map object.
delete player;
data_index = 0;
data_position = 0;
data_position_2 = 0;
}
这部分代码可以工作,但是对 monsters_file 和 monsters vector 做同样的事情会导致很多奇怪的错误。我得到的第一个错误是在将数据指针推入向量后删除指针时出现段错误。我检查了它,发现当它调用 SDL_FreeSurface() 时,程序在解构器中崩溃(segfault)。所以我检查了我的构造函数是否正确加载了表面。我发现构造一个对象一切正常,但是在调用 SurfaceLoad() 时它突然开始崩溃(segfault)。也检查了这个函数,一切都很好:指向表面的指针是好的,它返回的指针是好的,但由于某种原因它崩溃了:
sprite.image = SurfaceLoad (...);
一段时间后它在这里停止崩溃,没有任何理由(我只是添加了那行
if (surface_1 != surface_2) SDL_FreeSurface (surface_1);
,因为我注意到 SDL_DisplayFormat () 有时返回与指向未格式化表面的指针相同的指针。)并且当我 push_back 指向向量的指针指向的对象时开始崩溃(段错误):
this->area_map.monsters.push_back (*monster);
在创建游戏的这个阶段,Monster 和 Player 类几乎相同,所以我不知道为什么它可以毫无问题地创建玩家,并且创建怪物有这么多问题。有谁知道如何解决这个问题?