My sprite animation goes faster if the FPS is higher

Basically, what I do is:


	public void update(int delta) {
		
		time += delta;

		if (time >= interval) {

			time = 0;
			index++;
		}
		
		//draws the sprite: someSpriteArray[index].draw();
	}

The higher the FPS is, the faster the index variable increments.

Haha, call me dumb, but I’m out of ideas, I tried a lot of things to get it right, like multiplying by the current fps, among other nonsenses…

When I use the delta variable to multiply on movement stuff, like moving something, it works right.

I thought I only had to use the delta and everything would be goody-neat to go :confused:

Turns out to be that my entire life was a big lie. Any help is appreciated =o

Do you use any engine? It could be because you use a constant delta value or you smooth the delta value.

If time is 10*interval, you now have skipped 10 intervals.
Use a for loop


for(;time>=interval;time-=interval)
{
    index++;
}

Nope, I only use LWJGL, the delta I use is the one seen here

Sorry, I didn’t get it, wouldn’t this for-loop happen only once per call (since the time doesn’t reset to 0)?

Lets say the game freezes for a couple of seconds and you application doesn’t get enough CPU time. You get a temporary frame drop that and it takes much longer for your update routine to be called than usual.

Say your delta time was 5000 milliseconds and your interval is 1000 milliseconds. With your implementation,

We add 5000 to our time.

Is time >= 1000 ? Yes, so set time to zero, and move to the next frame - wait, what about those other 4000 seconds we totally discarded? Now we’re four frames behind and we’ll never catch up.

With my algorithm:

is 5000 > 1000? Yes, subtract 1000 from 5000, now it is 4000. Move to the next frame.
is 4000 > 1000 ? yes, subtract 1000 from 4000, now it is 3000, move to the next frame.

Etc

But after some loops the time will turn to be smaller then the interval and will no longer enter the for loop?

Also, on that for-loop, the index might increment more than one time per update call… making it skip some indices (sprite frames)

I use the update call to increment the index variable and use it to draw a sprite afterwards. If that for loop increments the index by “3” in a single update() call it will skip 3 frames…

I think we’re thinking on different scenarios, or I’m just not getting your thought :confused:

That’s the whole point - it should skip frames if it’s lagging behind.

Time will get smaller and smaller but you’re also adding deltaTime to it - and it only gets smaller when it is >= the interval at which you want to swap frames (and you swap frames.)

Here’s a couple excerpts from a thing - maybe they will help. For basic animation i simply check the System.currentTime() to a delay variable: (FPS has no effect):

private void updateEyes(long now) {
		if (now > lastBlink + blinkDelay) {
			blinking = !blinking;
			lastBlink = now;
			Bitmap tmp = eyes;
			eyes = blink;
			blink = tmp;
			int delay;
			if (blinking)
				delay = 100 + Game.random.nextInt(100);
			else
				delay = 400 + Game.random.nextInt(1400);
			blinkDelay = delay;
		}
	}

For animation based on movement I increment a variable based on the speed and pick a rounded index to pick the sprite image: (FPS has no effect):

private void updateLegs() {
		if (xspeed == 0) {
			legs = legsArray[legsArray.length / 2];
			legsImage = legsArray.length / 2;
		} else {
			legsImage -= xspeed * 0.2;

			int n = ((int) legsImage) % legsArray.length;

			while (n < 0) {
				n += legsArray.length;
			}

			legs = legsArray[n];
		}
	}

for a basic tile to tile movement, just turn down framerate

@Override
	public void init(GameContainer container, StateBasedGame game)
			throws SlickException {
		container.setTargetFrameRate(5);
	}

or you can do a if statement

@Override
	public void update(GameContainer container, StateBasedGame game, int delta)
			throws SlickException {
		container.getInput().enableKeyRepeat();

                

		double timercounter = .25;

		if (container.getInput().isKeyPressed(Input.KEY_RIGHT)) {
			if (player.canMoveRight()) {
                               if(timer = 0){
                               moveRight(); ////to keep it from lagging
}

				timer += timercounter;

				if (timer > 1) {
					moveRight(); /// then do again every 4 frames, 1 / .25 = 4
					timer = 0;
				}
			}
		}

make sure you have a private var called timer init to 0.