与Sprite纹理丢失链接

时间:2017-01-04 23:42:38

标签: c++ sfml

我有这个课程为我的游戏添加精灵:

\x10

我使用Pickup nameSprite()为我的游戏添加另一个精灵。但每次我这样做(我尝试使用不同的图像,我使用class Pickup { public: Pickup::Pickup() { Texture healthTexture; healthTexture.loadFromFile("health.png"); m_Sprite.setTexture(healthTexture); } Sprite Pickup::getSprite() { return m_Sprite; } private: Sprite m_Sprite; }; 来查看问题是否与图像有关)我只看到一个白色矩形而不是我想要的东西,似乎没有任何错误。我的问题是:链接问题的原因是什么?

1 个答案:

答案 0 :(得分:1)

SFML documentation州:

  

纹理参数指的是必须存在的纹理   精灵使用它。实际上,精灵并没有存储自己的副本   纹理,而是保持指向您传递给它的指针   这个功能。如果源纹理被破坏并且精灵尝试   使用它,行为是未定义的。

您创建和加载的纹理对象是构造函数的本地对象并在其末尾被销毁,因此一旦在程序执行中稍后实际使用它,Sprite-Object保留的指针/引用就会悬空。

为避免此问题,您可以将纹理另存为Pickup类中的其他成员。

正如Lorence Hernandez在下面的一篇富有洞察力的评论中指出的那样,这不是一个非常好的主意。每个Pickup实例都会拥有自己的纹理实例,尽管纹理相同,浪费内存。此外,Pickup无法再使用默认的复制操作,因为复制的Pickup的Sprite实例随后会引用原始对象中的纹理实例。

更好的方法是在Pickup类本身之外移动处理这个问题,即纹理实例的管理及其生命周期。 有许多可能的解决方案,从执行内部缓存的简单函数到更复杂的资源管理器类。

前者可以像下面的代码片段一样简单:

const Texture& load(const std::string &filename)
{
    static std::map<std::string,std::unique_ptr<Texture>> textures;
    auto &tex_ptr=textures[filename];
    if(!tex_ptr)
        tex_ptr=std::make_unique<Texture>(filename);
    return *tex_ptr;
}

当然,这个简单的版本确实存在轻微的“泄漏”,因为在程序执行期间永远不会释放未使用的纹理。

谷歌搜索“纹理管理器sfml”将产生许多关于后者的示例和教程,例如SFML的github中的this rather old unofficial one。它管理sf :: Image,而不是sf :: Texture,但是同样的一般想法适用。