I'm having trouble coming up with a way to animate these 2D isometric sprites. The sprites are stored like this:
(Game Folder Root)/Assets/Sprites/(Sprite Name)/(Sprite Animation)/(Sprite Direction)/(Frame Number).png
So for example,
/Assets/Sprites/Worker/Stand/North-East/01.png
Sprite sheets aren't really viable for this type of animation. The example stand animation is 61 frames. 61 frames for all 8 directions alone is huge, but there's more then just a standing animation for each sprite. Creating an sf::Texture for every image and every frame seems like it will take up a lot of memory and be hard to keep track of that many images. Unloading the image and loading the next one every single frame seems like it will do a lot of unnecessary work. What's the best way to handle this?
The reason I am not using a sprite sheet is because these sprites are hi-res images with many animations which all have a large quantity of frames. The resulting sprite sheet would be massive. In case you're wondering, here was my implementation of creating animated sprites.
// Animation class declaration
class Animation
{
public:
Animation(std::string path, int frames);
~Animation();
void nextFrame();
void gotoStart();
bool loadFrames();
sf::Texture& getActiveFrame();
private:
int frameCount;
std::string pathToAnimation;
int currentFrame;
sf::Texture frame[];
};
// Animation class implementation
Animation::Animation(std::string path, int frames)
{
pathToAnimation = path;
frameCount = frames;
}
Animation::~Animation()
{
// destructor
}
void Animation::nextFrame()
{
if(currentFrame < frameCount)
{
currentFrame = 1;
}
else
currentFrame += 1;
}
void Animation::gotoStart()
{
currentFrame = 1;
}
bool Animation::loadFrames()
{
for(int i = 01; i < frameCount; i++)
{
if(!frame[i].loadFromFile(pathToAnimation + std::to_string(i) + ".jpg")) return false;
}
return true;
}
sf::Texture& Animation::getActiveFrame()
{
return frame[currentFrame];
}
// Actor class declaration
class Actor
{
public:
Actor();
~Actor();
void setActiveAnimation(std::shared_ptr<Animation> anim);
void draw(sf::RenderWindow& win);
private:
sf::Sprite sprite;
std::shared_ptr<Animation> activeAnimation;
};
// Actor class implementation
Actor::Actor()
{
// constructor
}
Actor::~Actor()
{
// destructor
}
void Actor::setActiveAnimation(std::shared_ptr<Animation> anim)
{
activeAnimation = anim;
activeAnimation->gotoStart();
}
void Actor::draw(sf::RenderWindow& win)
{
sprite.setTexture(activeAnimation->getActiveFrame());
win.draw(sprite);
activeAnimation->nextFrame();
}
It's still not 100% where I'd like it to be but it's working and it's pretty easy to use.