I have an Armor
class that stores a texture and a sprite to be drawn to the screen like such:
Armor.h
class Armor
{
public:
Armor(const std::string& armorName);
void draw(sf::RenderWindow& window);
~Armor();
private:
sf::Texture armorTexture;
sf::Sprite armorSprite;
int numOfArmor;
};
Armor.cpp
#include "Armor.h"
Armor::Armor(const std::string& armorName)
{
armorTexture.loadFromFile(armorName);
armorSprite.setTexture(armorTexture);
numOfArmor = 0;
}
void Armor::draw(sf::RenderWindow& window)
{
window.draw(armorSprite);
}
Armor::~Armor()
{
}
I also have an object called Application
which stores an instance of Armor
in a map, like such:
Application.h
class Application
{
public:
Application();
void start();
~Application();
private:
sf::RenderWindow window;
std::map<std::string, Armor> armorMap;
std::map<std::string, Armor>::iterator armorIter;
};
Application.cpp
#include "Application.h"
Application::Application()
{
window.create(sf::VideoMode(640, 480), "SFML Application", sf::Style::Close);
window.setFramerateLimit(120);
std::string armorName;
std::ifstream file("Armors.txt");
while (file >> armorName)
armorMap.emplace(armorName, Armor(armorName + "Armor.png"));
file.close();
armorIter = armorMap.begin();
}
void Application::start()
{
while (window.isOpen())
{
sf::Event evnt;
while (window.pollEvent(evnt))
{
if (evnt.type == sf::Event::Closed)
window.close();
}
window.clear();
while (armorIter != armorMap.end())
{
armorIter->second.draw(window);
armorIter++;
}
armorIter = armorMap.begin();
window.display();
}
}
Application::~Application()
{
}
Whenever I construct the object, a white texture appears on the screen, which as I've found out is known as the white texture problem. I was stumped because I'm sure my texture wasn't getting destroyed, so I decided instead to change the map to std::map<std::string, Armor*> armorMap
and this fixed all my issues! Why would storing a pointer to an object of type Armor
in the map work, but not the way I initially did it?
When you store your armour object into the map you are making a copy of it, its texture and its sprite.
The sprite has stored your texture as a pointer to the original texture object which was destroyed (see https://www.sfml-dev.org/documentation/2.5.0/classsf_1_1Sprite.php#a3729c88d88ac38c19317c18e87242560).
Storing pointers in the map will give you much better performance anyway as you will avoid the unnecessary texture copies. You should probably be using std::shared_ptr<Armour>
rather than raw pointers unless you really know what you are doing.