You don't need a clock for each animation. You can just store and use the times for each animation using the same clock.
Loose example code:
sf::Clock clock;
sf::Time animation1FrameStartTime{ sf::Time::Zero };
sf::Time animation2FrameStartTime{ sf::Time::Zero };
sf::Time animation1FrameDuration{ sf::seconds(1.f / 12.f) }; // 12 frames per second
sf::Time animation2FrameDuration{ sf::seconds(1.f / 15.f) }; // 15 frames per second
// ...
// main loop
// ...
currentTime = clock.getElapsedTime();
if (currentTime - animation1FrameStartTime >= animation1FrameDuration)
{
increaseAnimation1Frame;
animation1FrameStartTime = currentTime;
}
if (currentTime - animation2FrameStartTime >= animation2FrameDuration)
{
increaseAnimation2Frame;
animation2FrameStartTime = currentTime;
}
This way, the
clock can be left to continue, the
frame durations are how long each frame should be shown (you might decide to not use different values for each animation), and the
frame start times keep track of when the current frame was started so you need one for each animation.
You may want to allow for times that pass the animation duration as that amount is currently ignored. You could use an accumulator or just increase the frame start time by the frame duration for each increase of the frame. Remember that it's possible that multiple animation frames may need to processed in just one loop cycle.
I'm not sure that "too many variables" is a bad thing. It's just keeping track of things that you need. You can tidy up things by grouping them into structs/classes.
Similarly, "shorter" isn't necessarily better either.
Since the frames in your example are consecutive frame numbers, you can calculate the frame by using the remainder from a division. Assuming that you still want to show one frame per second:
animation1frameNumber = static_cast<unsigned int>(clock.getElapsedTime().asSeconds()) % 3 + 1; // 3 because there are 3 frames.
animation2frameNumber = static_cast<unsigned int>(clock.getElapsedTime().asSeconds()) % 4 + 1; // 3 because there are 3 frames.
Just leave the clock running and that will calculate the frame number. Note that this only works with consecutive frame numbers. Other sequences will need other calculations. Note also the addition of 1; this is because the remainder will start from 0 but the frame numbers start from 1.
Short enough for you?
You can, of course, add other speed here by multiplying the time:
animation1frameNumber = static_cast<unsigned int>(clock.getElapsedTime().asSeconds() * 12.f) % 3 + 1; // 12 frames per second
animation2frameNumber = static_cast<unsigned int>(clock.getElapsedTime().asSeconds() * 15.f) % 4 + 1; // 15 frames per second
Note that this method assumes that the animation is linked to the clock and its position in the sequence will always be linked to the clock's time. You can, of course, use a pausable clock or keep track of time separately and use that instead in the calculations.
I probably should share this too:
If you use
Plinth (in particular, Plinth's SFML addition), you can use its "Frame Sequence" to animate these sorts of things automatically. Each frame of the animation is a unique key frame that can have the "frame ID" (number of which frame to display) as well as individual offsets, rotations etc.. Each frame of the animation can have its own duration to allow irregular frame rates and delays. Even the same frame ID used multiple times can have its own offsets etc.. In addition to this, all sequences can be set to not loop, loop in a cycle (which matches your examples), or loop in a ping pong fashion - as well as play in reverse. The current position of the sequence can be set by frame position or time, which would simplify working with clocks