gpt4 book ai didi

c++ - 在 SFML 2 中使用 Sprite vector 时如何停止出现白色方 block ?

转载 作者:行者123 更新时间:2023-12-03 06:57:55 25 4
gpt4 key购买 nike

我正在尝试制作 Sprite vector ,但前几个元素始终显示为白色方 block 。这些变量包含在 TileRPG 类中,然后在 main.cpp 中使用瓷砖.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++;
}
}

瓷砖.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, float x, float y, sf::RenderWindow& window);
};

最佳答案

问题

来自 sf::Sprite::setTexture() documentation :

the sprite doesn't store its own copy of the texture, but rather keeps a pointer to the one that you passed to this function.

所以,一个 sf::Sprite对象不存储 sf::Texture 的拷贝目的。顺便说一句,这与The Flyweight Pattern有关, 因为它可以从 sf::Sprite 's documentation 推断出来:

The separation of sf::Sprite and sf::Texture allows more flexibility and better performances: indeed a sf::Texture is a heavy resource, and any operation on it is slow (often too slow for real-time applications). On the other side, a sf::Sprite is a lightweight object which can use the pixel data of a sf::Texture and draw it with its own transformation/color/blending attributes.

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

可能的解决方案

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

另一种方法是调用 sf::Sprite::setTexture()之后您已正确填充 std::vector<sf::Texture>容器。这样,因为您不打算进一步插入 sf::Texture对象到 vector 中,它不会重新分配其内部缓冲区。

最后,关于容器的另一种方法是定义 m_texture作为std::vector<std::unique_ptr<sf::Texture>>反而。这样,如果 vector 的内部缓冲区发生重新分配,则只有 std::unique_ptr<sf::Texture> 的地址对象受到影响,不是pointee 对象的地址(即,不是 sf::Texture 对象的地址)。您也可以使用 boost::stable_vector 为了同样的目的。在这种情况下,您只需定义 m_texture作为boost::stable_vector<sf::Texture>相反。

关于c++ - 在 SFML 2 中使用 Sprite vector 时如何停止出现白色方 block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63764651/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com