Another big step is taken: The fundament of the new Animation API. I have reflected quite a long time on how to make everything more flexible without adding unnecessary complexity. I've come to the conclusion to diverge from the shared-ownership and inheritance approach, towards generic functors.
The core part is still
thor::Animator, it has become a class template.
template <class Animated, typename Id>
class Animator;
- Animated is the class that is being animated, for example sf::Sprite. Now it is possible to animate also other classes, like sf::Text or sf::Shape; even classes are not related to sf::Drawable at all.
- Id is the identifier type to distinguish the stored animations. Up to now, std::string has been enforced, now there can be any comparable type, such as an enum.
The class
thor::Animation was removed, there is no inheritance hierarchy anymore. The concrete animation class
thor::FrameAnimation is now a functor with a templated
operator(). The template parameter
Animated can be any class supporting
setTextureRect(). Mostly, this will be
sf::Sprite.
template <class Animated>
void operator() (Animated& animated, float progress) const;
In fact, everything that can be called with an object reference and a float is now an animation. This includes normal functions and lambda expressions. For instance, it requires a single line to define an animation
reverse that plays another animation
anim backwards:
auto reverse = [anim] (sf::Sprite& s, float pr) { return anim(s, 1.f - pr); };
(Imagine the amount of code for the same functionality with a traditional java-style class hierarchy)
Code that has looked like this:
thor::FrameAnimation::Ptr explosion = thor::FrameAnimation::create();
explosion.addFrame(1.f, sf::IntRect(...));
explosion.addFrame(1.5f, sf::IntRect(...));
thor::Animator animator;
animator.addAnimation("expl", explosion, sf::seconds(3));
now looks like this:
thor::FrameAnimation explosion;
explosion.addFrame(1.f, sf::IntRect(...));
explosion.addFrame(1.5f, sf::IntRect(...));
thor::Animator<sf::Sprite, std::string> animator;
animator.addAnimation("expl", explosion, sf::seconds(3));
The module is currently quite small, I have planned to add more animations (such as color gradients) as well as operational primitives (reverse, concatenate). However I'm not sure how much of this will be done before 2.0.