C++ 当使用带有SFML 2的sprite向量时,如何停止使用白色正方形?
我试图制作一个精灵向量,但前几个元素总是显示一个白色的正方形。 变量包含在TileRPG类中,然后在main.cpp中使用 tile.cpp 瓦片水电站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();
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);
};