Okay, I changed the animations to take a [0,1] progress instead of an absolute value. I believe, in the end things get simpler and more flexible (especially when it comes to playing parallel or serial animations). The drawback is that the absolute duration has to be specified at every animator, but since thor::Animator is a copyable class, it can be initialized once and copied for different sf::Sprite instances.
Stuff I am planning to implement next:
- Allow thor::FrameAnimation to change the image, not only the subrect of a sprite
- Create other thor::Animation derivates (probably the mentioned parallel and serial animations)
- Maybe transform thor::Animator into a template to allow other IDs than std::string. However I actually hate to transform such simple classes into templates, already because the whole implementation is required in the header
It should already be possible to implement the discussed interpolation/tweener feature relatively easy on user side:
class MyAnimation : public thor::Animation
{
public:
MyAnimation(thor::Animation::Ptr wrappedAnimation, std::function<float(float)> intervalTransformer)
: mAnimation(wrappedAnimation)
, mTransformer(intervalTransformer)
{
}
virtual void Apply(sf::Sprite& target, float progress) const
{
mAnimation->Apply(target, mTransformer(progress));
}
private:
thor::Animation::Ptr mAnimation;
std::function<float(float)> mTransformer;
};
Perhaps I can even take something like this into the public API. It would allow many things, such as reversing an animation, distorting the process, playing an animation multiple times, etc.
In fact, a std::tr1::function<void(sf::Sprite&, float)> might have been an interesting alternative to the whole thor::Animation class hierarchy... But probably the current approach is easier, especially for people not used to high-order functions and binders. In the end, it might require slightly more code because people cannot use super-compact std::tr1::bind() calls