Producing a Sprite Animation with JavaFX
While most of my posts so far dealt with JavaFX properties and bindings, today I want to write about another part of the JavaFX runtime I also work on: the animation API. In this article I will explain how to write custom animations in JavaFX and use this approach to create a class for sprite animations. (This will also be a good practice for one of my sessions at the conference 33rd Degree. I plan to write a game in JavaFX in just one hour. That’s going to be fun! )
There are many very good articles out there describing predefined Transitions (TranslateTransition, RotateTransition etc. ) and Timelines. Most of the time these approaches are sufficient, but in some cases one just needs more flexibility. And that is when the Transition class comes into play, which can be extended to define a custom animation.
To write your own animation class by extending Transition, two steps are required:
You can set the duration of a cycle by calling the protected method setCycleDuration(). Most of the time the duration is either fixed (if the animation is used only once) or configurable by the user. Almost all predefined Transitions in the JavaFX runtime fall into the second category. They expose their cycle duration via the duration property, you probably want to do that in your class, too. In rare cases the duration of a cycle depends on other values. For example the duration of a SequentialTransition and ParallelTransition depend on the duration of their children.
You can change the cycle duration as often as you like, but note that canada goose expedition grey for sale does not effect a currently running animation. Only after an animation is stopped and started again is the new cycle duration taken into account.
The interpolate() method is abstract and needs to be overridden. It defines actual behavior of the animation. The method interpolate() is called by the runtime in every frame while the animation is playing. A value frac, a double between 0. 0 and 1. 0 (both inclusive) is passed in, which specifies the current position. The value 0. 0 marks the start of the animation, the value 1. 0 the end. Any value in between defines the relative position. Note that a possible Interpolator is already taken into account when the value of frac is calculated.
To demonstrate how a custom transition is defined, we will look at a class that allows us to do Sprite animations. It takes an image that has several frames and moves the viewport from one frame to the other over time. We will test this class with the famous “The Horse in Motion” by Eadweard Muybridge. Enough talk, here is the code:
For the sake of simplicity, this example class just takes all parameters in the constructor and does not allow to change them later. In most cases this is sufficient.
The class expects an ImageView, the duration of a single cycle (that is how long canada goose expedition grey for sale should take to go through all frames), the number of frames, the number of columns (how many frames are in one row in the image), the offset of the first frame, and the width and height of all frames. The duration of the full cycle is passed to the super class by calling setCycleDuration(), all other values are stored. As a last step in the constructor, the interpolator is set to linear. By default an easing interpolator is set for all transitions, because that is what usually gives the best results. But in our case we want to run through all frames with the same speed and an easing interpolator would look weird.
The interpolate() method takes the passed in value and calculates which frame needs to be displayed at the moment. If canada goose expedition grey for sale changed since the last time interpolate() was called, the position of the new frame is calculated and the viewport of the ImageView set accordingly. That’s it.