Tino APCS

Sprite Animation

You can create a custom Transition (ex: animated sprite) by extending the Transition class. The advantage of extending the Transition class is that you'll have all the built-in functionality of any Transition. For example, you can speed up or slow down the animation, set its Duration, reverse it, etc. Using it will work the same as using any other Transition such as RotateTransition.

Here's a stripped down version:

class MySpriteAnimation extends Transition {  

    @Override
    protected void interpolate(double timeFraction) {
        // Must override this abstract method
    }
}  

JavaFX will automatically call the interpolate method after each tick of its own timer. The parameter given to you is the time as a percentage of the completion of one animation cycle. A value of 0 indicates the beginning of a cycle, a value of 1 indicates the end of a cycle, and a value between 0 and 1 indicates the relative time within a cycle.

To animate an image, you need to store each image of the animation and the Node the images will be displayed on. We'll use an array to store the images and an ImageView Node to draw the images on. A corresponding constructor has also been added.

class MySpriteAnimation extends Transition {

    Image[] imgArray;  
    ImageView imgView;  

    public MySpriteAnimation(ImageView imgView, Image... images) {
        super();
        this.imgView = imgView;
        imgArray = images;
    }  

    @Override
    protected void interpolate(double timeFraction) {
        // Must override this abstract method
    }
}  

The syntax Image... images used above is called Variable Arguments or Varargs for short. It's the special syntax used for declaring that a method takes infinite parameters (of one kind) from that point on. Java automatically puts these variable parameters into an array and you access them using array syntax. In the example above, the first parameter of our constructor is an ImageView but the remaining parameters are Image objects accessed by images[0], images[1], up to images.length - 1. We just dumped them directly into an array of Images.

Next we need to provide a way for the user to set the cycle Duration. We'll do this in the constructor but you could also provide a separate method.

class MySpriteAnimation extends Transition {

    Image[] imgArray;  
    ImageView imgView;  

    public MySpriteAnimation(ImageView imgView, Duration duration, Image... images) {
        super();
        this.imgView = imgView;
        this.setCycleDuration(duration);
        imgArray = images;
    }  

    @Override
    protected void interpolate(double timeFraction) {
        // Must override this abstract method
    }
}

Finally, you need to decide which Image to show at each frame of the animation.

class MySpriteAnimation extends Transition {

    Image[] imgArray;  
    ImageView imgView;  

    public MySpriteAnimation(ImageView imgView, Duration duration, Image... images) {
        super();
        this.imgView = imgView;
        this.setCycleDuration(duration);
        imgArray = images;
    }  


    @Override
    protected void interpolate(double timeFraction) {
        // Decide which Image to show, based on timeFraction. Left up to you.  
        int n = image # to show  

        // Show the image  
        imgView.setImage(imgArray[n]);
    }
}  

For example, if there were only two images in the animation then you could say:

if (timeFraction < 0.5)  
    imgView.setImage(imgArray[0]);  
else  
    imgView.setImage(imgArray[1]);

Once your MySpriteAnimation class is complete, using it is easy because it's just another Transition like RotateTransition or ScaleTransition.

ImageView node = new ImageView(new Image("file:img/frame_0.gif"));  
Image frame0 = new Image("file:img/num_0.gif");
Image frame1 = new Image("file:img/num_1.gif");
Image frame2 = new Image("file:img/num_2.gif");

MySpriteAnimation anim = new MySpriteAnimation(node, Duration.seconds(1), frame0, frame1, frame2);  

anim.setCycleCount(Animation.INDEFINITE);  // optional  
anim.setAutoReverse(true);  // optional  
anim.play();  

Now you have the ability to add animated objects to your programs.

Last modified: March 13, 2023

Back to Interpolation

Dark Mode

Outline