如何解决在SFML 2中使用精灵向量时,如何停止出现白色方块? 问题可能的解决方案
我正在尝试制作一个精灵矢量,但是前几个元素始终显示一个白色正方形。 变量包含在TileRPG类中,然后在main.cpp中使用 tile.cpp
void TileRPG::draw(int id,float x,float y,sf::RenderWindow& window) {
m_sprite[id].setPosition(sf::Vector2f(x,y));
window.draw(m_sprite[id]);
}
TileRPG::TileRPG() {
std::ifstream file { "data/tileRPGList.rf" };
std::string line{ "" },access { "" };
sf::Texture texture;
sf::Sprite sprite;
unsigned int i = 0;
while (std::getline(file,line)) {
m_texture.push_back(texture);
m_sprite.push_back(sprite);
access = "data/" + line;
m_texture[i].loadFromFile(access);
m_sprite[i].setTexture(m_texture[i]);
i++;
}
}
tile.hpp
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,sf::RenderWindow& window);
};
解决方法
问题
来自sf::Sprite::setTexture()
documentation:
精灵不会存储它自己的纹理副本,而是保留指向您传递给该函数的指针的指针。
因此,sf::Sprite
对象不存储sf::Texture
对象的副本。顺便说一下,这与The Flyweight Pattern有关,因为它可以从sf::Sprite
's documentation推断出来:
将
sf::Sprite
和sf::Texture
分开可以提供更大的灵活性和更好的性能:实际上,sf::Texture
是一种繁重的资源,并且对其执行的所有操作都很慢(对于实时间应用程序)。另一方面,sf::Sprite
是一个轻量级对象,可以使用sf::Texture
的像素数据并使用其自己的transform / color / blending属性对其进行绘制。
您代码中的m_texture
数据成员是sf::Texture
个对象的向量,即 std::vector<sf::Texture>
。如果没有足够的容量来存储要插入的push_back()
对象,则对其调用sf::Texture
将重新分配向量的内部缓冲区。因此,存储在sf::Texture
中的std::vector<sf::Texture>
对象在调用push_back()
之后可能最终位于内存中的其他位置。由于sf::Sprite
对象仅保留指向sf::Texture
对象的指针,因此如果sf::Texture
对象已重新分配到内存中的其他位置,这些指针将最终指向内存中的错误位置。
可能的解决方案
您只需调用std::vector::reserve()
即可为引导程序的内部缓冲区预先预留足够的内存。这种方法的缺点是,理想情况下,您需要预先知道向量将要存储的sf::Texture
个对象的数量,以免浪费内存。
另一种方法是仅在正确填充sf::Sprite::setTexture()
容器后之后调用std::vector<sf::Texture>
。这样,由于您不会在向量中进一步插入sf::Texture
个对象,因此不会重新分配其内部缓冲区。
最后,关于容器的另一种方法是将m_texture
定义为std::vector<std::unique_ptr<sf::Texture>>
。这样,如果发生向量的内部缓冲区的重新分配,则仅影响std::unique_ptr<sf::Texture>
对象的地址,不 pointee 对象的地址,(即不是sf::Texture
对象的地址)。您也可以将boost::stable_vector
用于相同的目的。在这种情况下,您只需将m_texture
定义为boost::stable_vector<sf::Texture>
。
Sprite::setTexture
不会复制纹理,但会存储指向该纹理的指针。一旦纹理矢量将其指针重新分配到随后的push_back
之一中,该指针便失效。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。