6
$\begingroup$

I am trying to figure out an algorithm for handling an otherwise simple animation. I have a progress bar that "ticks down" from a user specified amount of time to zero. I wanted a smooth animation, so I chose to update it in a timer class at approximately 24 frames-per-second. This works just fine.

The problem I am trying to figure out is how to speed up the animation at an arbitrary point in the animation cycle (the user will initiate it by pressing an "Update Now" type of button. So, say the timer/progress bar is running down from a 10 minute wait and they press "Update Now", I want the animation to "hurry up" and complete. This new rate would be as if the total wait time was 1 second. To put it another way, if the user waited half way though the normal timer even and pressed "Update Now", then there would only be a half-second left to animate. If they waited 75% of the time, then there would only be 250 ms left to animate, etc.

I have tried too many things to list and all have failed. Most notably, the progress bar jumps to a later time, and then finishes the animation--I can't get it to animate fast from the point where it has left off. I'm sure this is easy, I just can't quite grasp the correct algorithm.

Givens:

  • My timer is running at 24 frames-per-second for a smooth animation.
  • My current algorithm works by taking the countdown timer's initial value (in ms) and subtracting how much time has passed, also in ms, then calculating what percentage of time has passed for the progress bar.
  • One thing I tried of note, that does not work for me was to have a counter of how many frames I had to consume, and subtract a frame count every time my timer even entered. I then assumed I could increase the frame rate to simulate the faster time. This all failed miserably. I'm not sure why, but increasing the frame rate did not appear to do much on my computer--the speed increased, but not to the extent I wished for. Further, my timer is not reliable enough even when not doing the faster animation. It would gain approximately 1 second for every 10 seconds of original wait time. So, that method is off the table. If the user wanted to wait 60 seconds and didn't press "Update Now", then the timer would consistently run for approximately 70 seconds, a 120 seconds would become 140 seconds, etc. I'm doing this on an i7-6700 and the CPU is not strained (7-8% total), but something is causing the timer to be otherwise unreliable...

I'm sure the answer will turn out easy, but any help would be appreciated. I'm doing this in c#, but I am sure I can figure out any algorithm presented and translate it if needed.

$\endgroup$
3
$\begingroup$

You will need to persist the percent completed across frames and update it based on the time elapsed since last frame and the total time.

percentCompleted = 0;
totalTime = 10; //in seconds

void onUpdate(float deltaTime){
    percentCompleted += deltaTime/totalTime;
}

void hurryUp(){
    totalTime = 1;
}
$\endgroup$
  • $\begingroup$ Thanks, but that does not work for me. Here's the problem. Let's say you are 5 seconds into the countdown (percentCompleted = 0.5 or 50%). Then "Update Now" is pressed and totalTime is changed to 1. Now, when onUpdate is fired, percent complete will be 5 or 500%!! and there is no more animation as we have just flown way past 100% Or am I missing something? $\endgroup$ – Jim Aug 29 '16 at 20:30
  • 2
    $\begingroup$ no because at that point percent completed would remain at 0.5 % (the variables outside functions are the state kept across frames) and the next update would add a different delta based on the new totaltime as if the total time was always the new value. $\endgroup$ – ratchet freak Aug 29 '16 at 20:41
  • $\begingroup$ Ah, my mistake. I just didn't read it correctly the first time. Very good, just what I needed. $\endgroup$ – Jim Aug 30 '16 at 14:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.