Animation basics

Okay, so I’ve ventured into my first bit of java programming by making a Tetris clone.

One of the things I wanted to do is make it so the animation was very smooth to make it appear as though the pieces were sliding instead of moving down the grid block by block. I did accomplish this, by running a general animation thread that processes animations for the pieces.

You can take a look at the applet here…
username: guest
password: guest
http://www.grnade.com/tetris/

I’ve attached what my animation thread looks like if anyone wants to see what I mean.

Now heres the thing. I’m ready to add more animation to this to spice it up – you know, effects when you remove a line, perhaps making animations in the background, etc. The thing is my animation thread is going to get cluttered, and it doesn’t really make sense to have just one thread controlling all animations. It’s made timing things a real trick.

I know there is a better way to do this, I’m just looking for some sort of enlightenment here.
I tried giving each animation its own thread object by doing something like this:

    
Thread animateDrop = new Thread() {
        public void run() {
		if (yOffset>=20) {
			translate(0,1);
			yOffset = 0;
		} else
			yOffset++;
		try {
			sleep(speed/20);
		} catch (InterruptedException e) { }
        }
    };
    animateDrop.start();

The problem with that is objects with threads like that can’t interact with my yOffset variable(the variable that is added in my paint method to give the ‘sliding’ appearance)

So I guess my question is, whats the best way to tackle 2d animation where you could quite possibly have 6 or more animations going on at once? Is there a general consensus here? If anyone even has some good animation programming links, I’d love to see them.

First rule of gaming: Always keep your rendering in one thread.
Second rule of gaming: See rule #1

What you want to do is build objects that will render your special effects. For example, if you have an explosion to render, make a class like this:


public class Explosion
{
  private Image[] animation;
  private int x;
  private int y;
  private int counter = 0;

  public Explosion(Image[] animation, int x, int y)
  {
    this.animation = animation;
    this.x = x;
    thix.y = y;
  }

  public void render(Graphics g)
  {
    if(counter >= animation.length) return;

    g.drawImage(animation[counter], x, y, null);
    counter++;
  }

  public boolean isDone()
  {
    return (counter >= animation.length);
  }
}

To render the explosion, you’d just add it to an array list that you’ll loop through in your main rendering loop. When the animation claims that it’s done, you simply remove it from the list and allow it to be garbage collected.

The above example is, of course, very simplistic. A real-life example would probably include more counters (perhaps even particles all over creation) and a more complex positioning model, but the basic concept is the same.

Interesting…

you have it so the object itself draws to the graphic. i was painting the objects in the paint method by just painting with whatever the values are at the moment paint() is called.

just out of curiousity, what is the reasoning behind keeping all rendering to one thread?

Simplicity and synchronization. When you go multithreaded, you never quite know who’s changing data or writing to the backbuffer at a given time. This can result in a lot of difficult-to-debug situations where graphics will flicker, jump, tear, etc. Sometimes it can even screw up your logic causing the wrong thing to happen at the wrong time.

As luck would have it, it’s far simpler to ignore multithreading and do one thing after another. You’ve basically got 1/60th of a second to render everything you can to the backbuffer before the VSync happens. Once the VSync happens, your backbuffer will become the frontbuffer, and you’ll begin rendering the next frame. Since the point is to build the next frame of animation, there’s no real need to make anything happen concurrently.

As long as you keep things predictable, it’s very easy to write a game.

In general, action games do everything on a single thread.

(1) On a single core/CPU system its more efficient
(2) Games are step-wise time-based simulations. You want a single timebase to calculate input and reuslts in. In non-techie, that translates to “you want to worry about 1 frame at a time and get each frame exactly right.”