Rich Animations with Fluent Effects

With all my work on Shade I needed to create a number of animated effects. Naturally, I started by creating an object to address my needs, then I copied its functionality over and tweaked it, then I copied it again and tweaked it further. After the third time I realized that there should be a better way to create rich visual effects without having to reinvent the wheel each time. In the end, I wrote a small library to consolidate this behavior and simplify the creation of compelling effects, introducing Fluent Effects

Demo

Anyway, let’s cut to the chase. Here’s an example showing off how you might use Fluent Effects in a game:

Fluent Effects Demo

Downloads

For those of you who just want to dig in here’s the code:

Explanation

So what’s this all about? I started using David’s excellent SlickFx library. It works great but I found it to require a lot of boilerplate to do simple things. For instance, in Shade I have a number of types of text which simply fade in or out. To accomplish this with SlickFx you need to implement the AlphaEntity interface, configure an effect, and create a timeline. Furthermore, it requires working with images, which isn’t always desirable, for instance when working with fading score text.

So, with all that in mind I set about creating an interface that I would want to work with. There were a couple high level requirements:

  • Create compelling user experiences with rich effects
  • Concise and intuitive interface
  • Doesn’t force you to inherit or implement anything
  • Animate more than one property over the timeline
  • Chain actions together to create complex animations
  • No dependencies, runs on Java 1.5

To accomplish the above I opted to implement a fluent interface. This lets you configure your animations like so:

// play forward, wait one second, play backwards, loop three times
fx.forward().halt(1000).reverse().loop(3);

I’ve also created an annotation which allows you to concisely describe how a given property should be animated. For instance, you might try:

// alpha will go from zero to one over a second
@FluentProperty(start = 0, stop = 1, duration = 1000)
public void setAlpha(float a) { }

Of course, sometimes it’s not convenient to annotate your properties or you want to have multiple timelines for a single objects. In those cases you can configure the timeline programmatically:

// alpha will go from zero to one over a second
FluentConfig c = new FluentConfig();
c.add("setAlpha", 0, 1, 1000);

Finally, you put everything together like so:

// create a new timeline for the given object
Timeline fx = new Timeline(object);
// play forward, wait one second, play backwards, loop
fx.forward().halt(1000).backward().loop();
// start the animation
fx.start();
// advance the timeline some number of steps
fx.step(delta);

Conclusion

That completes the five minute tour. Please let me know if you find this useful or would like to see the full source code for the examples. Finally, if you have any suggestions for how to make the library better please let me know in the comments!

Comments

8 Responses to “Rich Animations with Fluent Effects”
  1. Gornova says:

    Hi again! I don’t know if i will use this library, but if you can, please put always many many examples with full sources of your ideas! :D

  2. aschearer says:

    Hey Gornova, sure thing. I wasn’t sure that was necessary since the library is really as easy to use as the example above, and I didn’t want to have to get everything tidy and ready for public consumption. Regardless, the source has been added to the list of downloads above, or you can just click here.

    I’ve included the source for the demo along with some documentation describing each object. In addition I’ve created a build file which you can use to quickly get up and running. Simply type “ant run” to start the demo on your machine.

  3. kev says:

    hi! the library i quite nice, but i do have a small problem. For the first time i create an object using a timeline (it is basically the same as your coin example, drawing a text instead of a sprite) my game gets stuck for a short (~0.3sec) , but noticeably time. the second time i create an object everthing works fine. do you know what might causes the problem?

  4. aschearer says:

    Sure thing, I’m not sure what the problem is off the top of my head but email me your code and I’ll take a look asap.

  5. Held says:

    Hi, the FluentObject work with reflection. I think that is a bad idea! An interface and a abstract calls with empty method is the better way. Little more performance? and you get compile and not runtime errors…

  6. aschearer says:

    Hey, you’re absolutely right that it uses reflection, and you’re also right about the potential cost associated with using reflection. The reason I chose to use reflection is so that I could create a library which you can drop into any project without having to update its hierarchies. Basically I wanted to create something that is orthogonal to your code so that it doesn’t create any unwanted dependencies. As for the cost, if you don’t have many effects I don’t think it should be a problem — profile your application to see if you’re really spending a lot of time with this library. Also, there is a precedent for this type of thing, check out Hibernate for a library which does something similar but for data binding and ORM’ing.

    Naturally, if you think it should be done differently feel free to make that change! If you send it back here or somehow alert me to it I will help spread the word.

  7. gilley55 says:

    i am going to be using your Fluent Effects code in my game and i will be giving you credit for it.

    Thanks for sharing it.

  8. gilley55 says:

    i am going to be using your Fluent Effects code in my game and i will be giving you credit for it.


    Thanks for sharing it.

Leave A Comment