Thursday, July 12, 2007

Timed Animation

Switching Images


Ok so one of the things that you might want to do after figuring out how to draw images on the screen that were loaded from a file is to animate a bunch of images. One of the main concepts to making animation is switching between images. To do this we simply use an indexed array of images to represent our animation.
// A collection of frames used for animation.
private ArrayList frames = new ArrayList();
This means that each frame or image has an integer position in the array. We can use this to position to move to the next frame or even to wrap around to rewind to the first frame. So we'll need to keep track of our current frame.
// An integer representing the current frame to display.
private int animation_frame = 0;
Likewise we will need the first frame of our animation and also the last. The first frame in this case will be zero or the beginning index in the Array you could actually create another variable for the beginning position so that you can randomize it for explosions or other effects. The last frame is of course the last index in the ArrayList and that will be frames.size()-1. We will be checking to make sure that our animation_frame variable value stays within zero and frames.size()-1 other wise an ArrayIndexOutOfBounds exception will be thrown.

Drawing The Current Frame


So now that we have a list of images (frames) that will become our animation we want to be able to draw the current image in the list that corresponds to the index animation_frame. This is how we would draw it using a Graphics object.
g.drawImage((Image)frames.get(animation_frame), 10, 150, null);
As you can see its pretty simple. We can substitute the second and third parameters for the x and y position respectively. In another post I will show how to vary these two parameters over time in order to obtain certain movement and physics effects. There are also additional methods for drawImage within the graphics object one in particular allows you to set the width and height of the image you are drawing which allows for a lot more effects in game.

Changing The Frame


Ok so we are displaying the current image in the list of frames for our animation now we want to cycle or loop through the entire list but we only want to change a frame at a fixed interval of time. For this we will use a timer. And so we create a java.util.TimerTask which will increment the animation_frame variable thus moving to the next image in the list.

We need to check after we change the variable to make sure that we have not reached the last frame if we have then we want to loop back to the first image in the list.
TimerTask animationTask = new TimerTask() {
   public void run() {
      //move the animation to the next frame.
      animation_frame++;

      //check to see if we have finished all frames.
      if( animation_frame >= frames.size() ) {
     
         //rewind to the beginning of the animation.
         animation_frame = 0;
      }
    }
};
Now we can schedule the TimerTask with the java.util.Timer and give it an interval on which to change frames.
// set the animation to run at 2 frames per second.
timer.schedule(animationTask,0,500);
So that is pretty much all you need to create animations.

Seeing Is Believing

2 comments:

Anonymous said...

hello.. i have a question regarding this double buffering stuff.. is this code supposed to clear any flickering already?? since i think in here u implemented double buffering already..

Nick said...

This example uses an old double buffering solution. Swing does do double buffering though you can still get flickering if any fillRect or clearRect results are displayed to the user.

Flickering occurs only because you need a clear surface to draw on each frame and in order to do that you need to clear everything, or at least redraw everything over whats in the buffer.

How to use BufferStrategy in Java so far is a much better solution for performance than this example uses. So far that I've seen it's capable of better frame rates.

I really do need to create a new post on how I currently do timed animation and replace this ones side link.

I appreciate the question, i'd like to get into some more advanced topics of animation rendering when I can find time to write the article.

Post a Comment