EDIT:
Here's the improved version:
#include <SFML/Graphics.hpp>
#include <memory>
#include <map>
enum SpriteId
{
ITEM1,
ITEM2,
ITEM3,
ITEM4,
ITEM5
};
const int WIDTH = 100;
const int HEIGHT = 100;
typedef std::tr1::shared_ptr< sf::Sprite > SpritePtr;
typedef std::map< SpriteId, SpritePtr > SpriteMap;
typedef std::map< SpriteId, SpritePtr >::iterator iter;
class SpriteManager
{
private:
SpriteMap spriteMap;
sf::Texture& m_texture;
void clipSprite(SpriteId name)
{
spriteMap.at(name)->setTexture(m_texture);
switch(name)
{
case ITEM1: spriteMap.at(name)->setTextureRect(sf::IntRect(0,0,WIDTH,HEIGHT));break;
case ITEM2: spriteMap.at(name)->setTextureRect(sf::IntRect((1*WIDTH),0,WIDTH,HEIGHT));break;
case ITEM3: spriteMap.at(name)->setTextureRect(sf::IntRect((2*WIDTH),0,WIDTH,HEIGHT));break;
case ITEM4: spriteMap.at(name)->setTextureRect(sf::IntRect((3*WIDTH),0,WIDTH,HEIGHT));break;
case ITEM5: spriteMap.at(name)->setTextureRect(sf::IntRect((4*WIDTH),0,WIDTH,HEIGHT));break;
//default: should i create a special "Error" sprite and load it, akin to Valve's ERROR models?
// or maybe create and throw an exception.
}
}
public:
SpriteManager(sf::Texture& texture) : m_texture(texture)
{}
SpritePtr getSprite(SpriteId name)
{
if(!spriteMap[name])
{
spriteMap[name] = std::tr1::make_shared< sf::Sprite >();
clipSprite(name);
return spriteMap[name];
}
else
return spriteMap[name];
}
// I can call reset for each pointer to force them to deallocate,
// but that would just be replicating the initial raw pointer problem
// I don't really need a destructor here, right?
//~SpriteManager()
//{
// for(iter i = spriteMap.begin(); i != spriteMap.end(); ++i )
// {
// i->second.reset();
// }
//}
};
int main()
{
sf::RenderWindow window(sf::VideoMode(800,600), "Test", sf::Style::Titlebar | sf::Style::Close);
sf::RectangleShape background(sf::Vector2f(800.0f,600.0f));
window.setFramerateLimit(30);
sf::Texture spriteSheet;
if(!spriteSheet.loadFromFile("SpriteSheet.png"))
{
return 1;
}
SpriteManager sprites(spriteSheet);
SpritePtr sprite = sprites.getSprite(ITEM1);
SpritePtr sprite2 = sprites.getSprite(ITEM2);
sprite->setPosition(100,100);
sprite2->setPosition(200,100);
while(window.isOpen())
{
sf::Event event;
while( window.pollEvent(event))
{
if(event.type == sf::Event::Closed)
{
window.close();
}
}
window.clear();
window.draw(background);
window.draw(*sprite);
window.draw(*sprite2);
window.display();
}
return 0;
}
A thing to note here that this is just an example; it's a test model. That is why everything is in a single .cpp file and the item names are not descriptive.