C++ 当使用带有SFML 2的sprite向量时,如何停止使用白色正方形?

C++ 当使用带有SFML 2的sprite向量时,如何停止使用白色正方形?,c++,sfml,C++,Sfml,我试图制作一个精灵向量,但前几个元素总是显示一个白色的正方形。 变量包含在TileRPG类中,然后在main.cpp中使用 tile.cpp 瓦片水电站 class Tile { protected: std::vector<sf::Texture> m_texture; std::vector<sf::Sprite> m_sprite; }; class TileRPG : public Tile { public: TileRPG();

我试图制作一个精灵向量,但前几个元素总是显示一个白色的正方形。 变量包含在TileRPG类中,然后在main.cpp中使用 tile.cpp

瓦片水电站

class Tile {
protected:
    std::vector<sf::Texture> m_texture;
    std::vector<sf::Sprite> m_sprite;
};

class TileRPG : public Tile {
public:
    TileRPG();
    void draw(int id, float x, float y, sf::RenderWindow& window);
};
类平铺{
受保护的:
std::向量m_纹理;
std::向量m_精灵;
};
类别TileRPG:公共Tile{
公众:
TileRPG();
虚线绘制(int-id、float x、float y、sf::RenderWindow和window);
};

Sprite::setTexture不复制纹理,但存储指向纹理的指针。一旦纹理向量在随后的
push_-back
s中重新分配其存储,该指针将失效。

问题 从:

精灵不存储自己的纹理副本,而是保留一个指向传递给此函数的纹理副本的指针

因此,
sf::Sprite
对象不存储
sf::Texture
对象的副本。顺便说一句,这与以下因素有关:

sf::Sprite
sf::Texture
分离,可以实现更大的灵活性和更好的性能:事实上
sf::Texture
是一项繁重的资源,对它的任何操作都很慢(对于实时应用程序来说通常太慢)。另一方面,
sf::Sprite
是一个轻量级对象,它可以使用
sf::Texture
的像素数据,并使用自己的变换/颜色/混合属性绘制它

代码中的
m_texture
数据成员是
sf::texture
对象的向量,即
std::vector
。如果向量没有足够的容量来存储要插入的
sf::Texture
对象,则对其调用
push_back()
将重新分配向量的内部缓冲区。因此,在调用
push_back()
之后,存储在
std::vector
中的
sf::Texture
对象可能最终位于内存中的不同位置。由于
sf::Sprite
对象只保留指向
sf::Texture
对象的指针,如果
sf::Texture
对象已在内存中的其他位置重新分配,这些指针将最终指向内存中的错误位置

可能的解决方案 您只需调用
std::vector::reserve()
预先为向量的内部缓冲区保留足够的内存。这种方法的缺点是,理想情况下,您需要提前知道向量将要存储的
sf::Texture
对象的数量,以避免浪费内存

另一种方法是在正确填充
std::vector
容器之后,仅调用
sf::Sprite::setTexture()
。这样,由于您不打算进一步将
sf::Texture
对象插入向量,因此它不会重新分配其内部缓冲区

最后,关于容器的另一种方法是将
m_纹理
定义为
std::vector
。这样,如果重新分配向量的内部缓冲区,则只影响
std::unique_ptr
对象的地址,不影响指针对象的地址(即,不影响
sf::Texture
对象的地址)。您也可以将其用于相同的目的。在本例中,您只需将
m_纹理
定义为
boost::stable_vector

class Tile {
protected:
    std::vector<sf::Texture> m_texture;
    std::vector<sf::Sprite> m_sprite;
};

class TileRPG : public Tile {
public:
    TileRPG();
    void draw(int id, float x, float y, sf::RenderWindow& window);
};