2017-02-28 87 views
0

我的游戏世界中的每个对象都有一个可视化表示该对象的精灵矢量。我的问题是,我似乎无法正确绘制在屏幕上:从精灵矢量绘制SFML

这是绘制对象,从每一个绘制继承:

class Drawable { 
private: 
    static vector<Drawable*> sprites; 
protected: 
    vector<sf::Texture> myTextures; 
    vector<sf::Sprite> mySprites; 
public: 
    Drawable(); 
    static vector<Drawable*> getSprites(); 
    void draw(sf::RenderWindow&) const; 
}; 

而且它的.cpp:

vector<Drawable*> Drawable::drawables; 
Drawable::Drawable() { 
    drawables.push_back(this); 
} 

vector<Drawable*> Drawable::getDrawables() { 
    return drawables; 
} 

void Drawable::draw(sf::RenderWindow& window) const { 
    for (auto sprite : mySprites) { 
     window.draw(sprite); 
    } 
} 

例从绘制继承的对象的:

class Terrain : public Drawable { 
private: 
    void loadSprite(string); 
public: 
    Terrain(string); 
}; 

及其的.cpp:

Terrain::Terrain(string fileName) { 
    loadSprite(fileName); 
} 

void Terrain::loadSprite(string fileName) { 
    sf::Texture texture; 
    texture.loadFromFile(fileName); 
    myTextures.push_back(texture); 

    sf::Sprite sprite; 
    sprite.setTexture(texture); 
    mySprites.push_back(sprite); 
} 

在这种情况下,地形精灵在运行时只是一个白盒子。我认为这是因为loadSprite中的“texture”和“sprite”var在方法超出范围后被破坏。

我知道我可以通过在地形类中保存“纹理”和“精灵”来解决这个问题(不是像现在这样在本地创建它们)。但这对我来说似乎没有必要,我不能将它们存储在mySprites和myTextures的矢量中?

回答

3

我认为这是因为loadSprite中的“texture”和“sprite”var在方法超出范围后被破坏。

你说得对。 sf::Sprite stores a reference to sf::TextureloadSprite只有在你做sprite.setTexture(myTextures.back());时才能工作一次。但std::vector的元素将被重新分配为push_back。为了简单起见,我建议使用std::vector<std::shared_ptr<sf::Texture>>

更好的是,一次加载所有纹理,以便您没有重复个人并使用ID来引用它们。

+0

感谢您的意见,我尝试了我想出的方法。那就是将精灵和纹理存储在每个使用它们的对象中。所以terrain.h会有两个字段sf :: Texture texture,sf :: Sprite sprite,并且在loadSprite中,我分配了它们并且它工作:) – Binbon

+0

另外,我更改了以使mySprites和myTextures矢量现在拥有指针(而不是制作副本)这将防止重复 – Binbon