Accurate Animation

Hello peoples.

I was wondering if someone could tell me if this was a good idea of how to do animation and other time based tasks.

Its a work around I made so I would not have to use Threads to time things.


/*
 * Manages different rates based on what the rate is for the main loop 
 * of a game.
 */
public class RateManager 
{
	// The current update step
	private int currentUpdate;
	// The rate that we will reset at.
	private int rate;
	// The main rate of the loop
	private int mainRate;
	
	/*
	 * Takes the rate that you would like to update from and 
	 * divides it by the mainRate which will result in a fairly accurate
	 * update rate.    
	 * @param newRate			the rate of this manager
	 * @param newMainRate		the mainRate for this manager
	 */
	public RateManager( int newRate, int newMainRate )
	{
		this.rate = newRate / newMainRate;
		this.mainRate = newMainRate;
		this.currentUpdate = 0;
	}
	
	/*
	 * This will return a boolean showing whether this Manager has reached the end of its
	 * rate. It will then reset and wait for another update.
	 * @return True if it hit the end and false if not. 
	 */
	public boolean update()
	{
		if( this.currentUpdate == this.rate )
		{
			this.currentUpdate = 0;
			return true;
		}
		else
		{
			this.currentUpdate++;
			return false;
		}
	}
	
	/*
	 * Sets a new rate based on the  mainRate already in the manager.
	 * @param newRate the new rate for this manager
	 */
	public void setRate( int newRate )
	{
		this.rate = newRate / this.mainRate;
	}
	
	/*
	 * Sets a new rate and a new mainRate for this manager
	 * @param newRate			new rate
	 * @param newMainRate		new mainRate
	 */
	public void setRate( int newRate, int newMainRate )
	{
		this.rate = newRate / newMainRate;
		this.mainRate = newMainRate;
	}

}

Basically, if you were updating a loop with Thread.sleep(someTime)

you could animate/time/whatever by having an object that you create that would get the amount of updates
it would take for it to “update” based on what speed you’re main loop is running at.

Lets say we are sleeping our loop every 33mils so about 30fps and we want something to shoot off every 280mils.
Then we create a object that will see how many times the main loop needs to update before it would shoot off.
So we update the object and it will return whether it has shot off or not.

I don’t quite understand what you are doing with the rate and mainRate.

How about this Animation class? I use a private internal class called Frame that stores the image and the time that frame ends. Then you call update every tick with the deltaTime and getFrame to get the current image.

So basically say you have your thread sleep every 16 milliseconds but you want a sprite/animation to change or update every 280 milliseconds.
Then you divide 280 by 16 and that will give you your “delta” the amount of updates n the main thread before you need to change frames.

My question is “is this a valid way of animating?”

I have tried it and it works for particles/emitters and it works for animations but I don’t know if there is a better cleaner method that does not involve threads.

Well instead of doing all this math, my Animation class allows you just to set the number of milliseconds each frame runs at and updates accordingly. Your way depends on a steady game loop so if there is a slow down, things might get messed up.

Very simple animation class:
https://code.google.com/p/libgdx/source/browse/trunk/gdx/src/com/badlogic/gdx/graphics/g2d/Animation.java
Note this is structured to allow you to keep the state time in your model. You can store a state and a state time in your model, then when it comes time to draw, look up which animation to use based on the state and then pass the state time to the animation to get the correct frame, then draw that.

Interesting very similar to my idea but more polished.

Hmmm…basically you want the animation/timer to be able to update without much reliance on the main loop.

Contributing…

public class Animation {

	public Animation(Frame[] frames) {
		this.frames = frames;
	}

	public Animation(BufferedImage[] frames, int delay) {
		this.frames = new Frame[frames.length];
		for (int i = 0; i < frames.length; i++) {
			this.frames[i] = new Frame(frames[i]);
			this.frames[i].delay = delay;
		}
	}

	public final Frame[] frames;

	private long start = -1;
	private int last = 0;

	public final BufferedImage lastImage() {
		return frames[last].image;
	}

	public final int frame() { // Gets the current frame's index position based on the internal 'frames' array
		if (start == -1) {
			start = System.nanoTime() / 1000000;
		}
		long now = System.nanoTime() / 1000000;
		long elapse = now - start;
		if (elapse >= frames[last].delay) {
			start = now;
			return last = ++last % frames.length;
		}
		return last;
	}

	public final int width(int frame) {
		return frames[frame].image.getWidth();
	}

	public final int height(int frame) {
		return frames[frame].image.getHeight();
	}

	public final int draw(Graphics2D g, int x, int y) {
		int frame = frame();
		g.drawImage(frames[frame].image, x, y, null);
		return frame;
	}

	public final void reset() {
		start = -1;
	}

}


public class Frame {

	public Frame() {
		this(128, 128);
	}

	public Frame(BufferedImage image) {
		this.image = image;
	}

	public Frame(int w, int h) {
		image = Misc.createBufferedImage(w, h);
	}

	public Frame(Frame copy) {
		image = Misc.clone(copy.image);
		delay = copy.delay;
		opacity = copy.opacity;
	}

	public final BufferedImage image;

	public int delay = 50;

	public int opacity = 100;

}

Your probably not gonna need a separate size for each frame, or that opacity variable in the Frame class either, I use them elsewhere in the program. This works well enough for me, it’s pretty smooth, it’s independent of game loop/rendering loop. I don’t need to dynamically add frames once an animation object is created but it would be an easy edit.

I like that alot counterp.

But the code I was trying to make would be something that could be used not just for animation but for anything that needs a separate update time than the main loop.

Unfortunately my code relies on some constant amount of time that the main loop is updating at.

…Looks like I am going to look into the getNano time a bit more.

Something like java.util.Timer?

java.util.Timer uses separate threads…

no, it’s single threaded

and what OP is doing is basically how Timer class works, except that the Timer class is not concerned about how many cycles there have been, but it works by waiting until the next task (the one with the shortest delay between now and its execution) is ready to be executed. (i would write my own implementation if you need really high accuracy)

So I could use the Timer class for animation?

Wow I always thought it ran a new Thread.

But no super accuracy is not important just want good timing for emitters and sprite animations for program I am making.

The Timer class runs 1 thread for all its TimerTasks so it will be a different thread from your game loop, therefore you will have to turn your game loop into a TimerTask.

I think the Timer class might be too clunky to use for your game loop, you shbould rip the implementation and strip it down if you can