处理曲面向量时如何正确使用 SDL_FreeSurface

Posted

技术标签:

【中文标题】处理曲面向量时如何正确使用 SDL_FreeSurface【英文标题】:How do I correctly use SDL_FreeSurface when dealing with a vector of surfaces 【发布时间】:2009-11-13 14:53:36 【问题描述】:

我在 SDL 中为自己设置了一个小型射击游戏作为教程。我有一个弹丸结构

struct projectile

    SDL_Surface* surface;
    int x;
    int y;
;

然后我把它放入一个向量中。

vector<projectile> shot;
projectile one_shot;

当我按下空格键时,我会创建一个新的射弹并将其添加到向量中,然后在渲染时它们会被 blitted。

这工作正常,但我在看似随机的情况下收到“程序已停止工作”错误。

所以我想知道释放表面的正确方法是什么。

之后我会释放它们吗? 我是否会在每个单独的镜头退出屏幕时释放它? 或者其他选择?

更新:

我发现当我退出时它崩溃的地方,当我开了几枪并且它们都退出了屏幕时。我尝试用“正确的复制方式”替换为seen in this example 将曲面添加到向量的代码,它的行为仍然相同。

这就是我释放表面的方式。

if(shot.at(i).y < 0 - shot.at(i).surface->h)

    SDL_FreeSurface(shot.at(i).surface);
    shot.erase(shot.begin() + i);

任何人都有一个想法或一些示例代码,我可以看看这个来解决这个问题。

【问题讨论】:

【参考方案1】:

如果多个射弹使用相同的精灵(就像在几乎所有基于精灵的游戏中一样),最好使用包含游戏使用的所有图像的图像缓存并仅在那里进行内存管理。在开始时或按需填充并在退出时冲洗。然后射弹只需要向这个缓存请求一个指向“arrow.png”的指针,缓存会加载它(如果需要)并返回表面指针。

这样的缓存可以是一个简单的 std::map,只有 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");
    ...

【讨论】:

我已经接受了这个解决方案,因为我稍后会在路上使用这样的东西。谢谢。【参考方案2】:

你应该在摧毁射弹时释放表面。何时摧毁弹丸是游戏设计决定;可能是它最迟离开屏幕时,当然也可能是(如果)它击中目标时。

【讨论】:

【参考方案3】:

您是否也在其他地方使用相同的表面?因为如果是这样,只要在其他地方使用,就无法释放它。

如果您不这样做:构建/加载您的表面并在射弹的构造函数/析构函数中释放。即:

struct projectile 
    SDL_Surface* surface;

    projectile() : surface(NULL) 
        surface = LoadImage(...);
    

    ~projectile() 
        if(surface) 
             SDL_FreeSurface(surface);
             surface = NULL;
        
    

;

【讨论】:

我认为这可能会引导我走向正确的方向。我正在处理代码,因为添加它不能 100% 工作(当我开第二枪时崩溃)

以上是关于处理曲面向量时如何正确使用 SDL_FreeSurface的主要内容,如果未能解决你的问题,请参考以下文章

点云法线

计算几何---曲面三角形差值公式

二重积分计算曲面表面积

尝试使用 MATLAB 绘制 z = x + y 时图形不正确

如何知道向量的正确最大大小?最大尺寸()?但不是

离散点云的法向量如何计算?