我已经在SDL中设置了一个小型射击游戏作为我自己的教程。我有一个射弹结构
struct projectile
{
SDL_Surface* surface;
int x;
int y;
};
我把它放到矢量中。
vector<projectile> shot;
projectile one_shot;
当我按下空格时,我会创建一个新的射弹并将其添加到矢量中,然后在渲染时它们会被渲染。
这样可以正常工作,但我看似随意的情况下“程序已停止工作”错误。
所以我想知道释放表面的正确方法是什么。
更新:
我已经找到了当我退出时崩溃的地方,当我开了几枪并且他们都退出了屏幕。我已经尝试用“{3}}的”正确复制方式“替换将表面添加到向量的代码,并且它仍然以相同的方式运行。
这就是我释放表面的方式。
if(shot.at(i).y < 0 - shot.at(i).surface->h)
{
SDL_FreeSurface(shot.at(i).surface);
shot.erase(shot.begin() + i);
}
任何人都有一个想法或一些示例代码我可以看一下来解决这个问题。
答案 0 :(得分:2)
如果几个射弹使用相同的精灵(几乎所有基于精灵的游戏),最好使用包含游戏使用的所有图像的图像缓存,并仅在那里进行内存管理。在开始或按需填充它并在退出时冲洗它。然后抛射物只需要向此缓存询问一个指向“arrow.png”的指针,缓存加载它(如果需要)并返回表面指针。
这样的缓存可以是一个简单的std :: map&lt; string,SDL ___ Surface *&gt;只使用get_surface(string)和flush()等函数。
编辑:这个想法的实现:
class image_cache{
map<string, SDL_Surface*> cache_;
public:
SDL_Surface* get_image(string file){
map<string, SDL_Surface*>::iterator i = cache_.find(file);
if(i == cache_.end()) {
SDL_Surface* surf = SDL_LoadBMP(file.c_str());
i = cache_.insert(i, make_pair(file, surf));
}
return i->second;
}
void flush(){
map<string, SDL_Surface*>::iterator i = cache_.begin();
for(;i != cache_.end();++i)
SDL_FreeSurface(i->second);
cache_.clear();
}
~image_cache() {flush();}
};
image_cache images;
// you can also use specialized caches instead of a global one
image_cache projectiles_images;
int main()
{
...
SDL_Surface* surf = images.get_image("sprite.png");
...
}
答案 1 :(得分:1)
当你摧毁抛射物时,你应该释放表面。当你摧毁弹丸是游戏设计的决定;可能是它最迟离开屏幕的时候,当然还有(如果)它击中了目标。
答案 2 :(得分:0)
您是否也在其他地方使用相同的表面?因为如果是这样的话,只要在其他地方使用它就不能释放它。
如果你不这样做:在弹丸的构造函数/析构函数中构建/加载曲面和释放。即:
struct projectile {
SDL_Surface* surface;
projectile() : surface(NULL) {
surface = LoadImage(...);
}
~projectile() {
if(surface) {
SDL_FreeSurface(surface);
surface = NULL;
}
}
};