![]() |
|
time based movements = slow animation |
Pawel B
Member #5,231
November 2004
|
I added a timer in the beginning of my render function and at the end. I compute the seconds that have gone by (about 0.02seconds) and used that to multiply the object's velocity. I had to change my velocity number from 5.0 to 360 for the object to go about the same speed as it did without the timer. If I pay attention closely I can see that the animation is choppy but like I said I have to pay attention very closely. Am I missing something? |
Fladimir da Gorf
Member #1,565
October 2001
![]() |
The way I do it is to have a target fps like 100 which you intend your game to be run in (and design the speeds such that everything looks fine in 100 fps). Then multiply all the speeds and accelerations by float(TARGET_FPS)/float(currentFps). If the current fps is half of the target fps the objects will move twise as much every frame and so on. OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori) |
james_lohr
Member #1,947
February 2002
|
Quote: Then multiply all the speeds and accelerations by float(TARGET_FPS)/float(currentFps) That's just wrong. It's ok to multiply the velocity by this ratio if the velocity is constant, but multiplying the acceleration by this value will screw up the physics.
|
Fladimir da Gorf
Member #1,565
October 2001
![]() |
No it doesn't. Maybe I didn't explain myself well. That's because float(TARGET_FPS)/float(currentFps) is actually the delta time between frames. And as you know the acceleration is the change in speed per time unit just as the movement is a change in position per time unit. Like: speed += dt * acceleration; position += dt * speed; I've always done it this way and I can say that it works. OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori) |
Pawel B
Member #5,231
November 2004
|
Thank you sooo much it works perfectly. Is there anything else I should be doing with timers except moving objects? |
Fladimir da Gorf
Member #1,565
October 2001
![]() |
Use it everywhere where you have some kind of a speed (rotation speed, fading speed, color changing speed) or acceleration (increase in turn rate, although a very rare occasion). OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori) |
james_lohr
Member #1,947
February 2002
|
Quote: speed += dt * acceleration; Sorry, you're absolutely right. I was thinking about dampening eg: speed *= 0.99 ...I suppose this isn't a problem either 'cause you can write it as: speed = speed - speed*(1-0.99); or: speed += speed*(0.99-1); which works fine with what you gave: speed += dt * speed*(0.99-1); If fact I don't know what I was thinking of... probably just being an idiot.
|
Fladimir da Gorf
Member #1,565
October 2001
![]() |
Well, I could've said it clearer than this: Quote: Then multiply all the speeds and accelerations by float(TARGET_FPS)/float(currentFps). You could read that as this: speed *= dt; which is wrong, as I mean speed += dt * acceleration; and so on. OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori) |
Thomas Harte
Member #33
April 2000
![]() |
So, to sum up: the original poster was using time deltas calculated exactly from one frame to the next and Fladimir's fix is to use an averaging of those time deltas to avoid the low resolution Allegro timer problems. Personally I do exactly the same thing, but have found that averaging only over the last three or four frames is sufficient - no need to average over an entire second or whatever (typically longer than 4 frame) period you calculate FPS over. [My site] [Tetrominoes] |
Jakub Wasilewski
Member #3,653
June 2003
![]() |
Quote: speed += dt * speed*(0.99-1); This won't work as expected, and will result in more dampening at lower framerates. Examine two possibilities:
When dampening you should use a formula like: speed *= std::pow(dampeningFactor, dt) That way, you achieve consistent results regardless of the framerate. The differences in my example may seem small, but at 100 logic frames per second, the difference between particular framerates is noticable. I ran into this when developing SWB, which uses delta time. Bullets are affected by air friction (constant dampening factor for speed), and stay in the air for 6, 7 seconds. The AI usually missed its mark, about 10 pixels short, when it should be perfect. Why? Because it used lower resolution for bullet prediction (dt = 50ms) than the game itself (dt maintained around 10ms), and because I used a faulty formula without the pow. I hope that it didn't sound like an "I'm smart, you're not" statement. It's just that I ran into that problem earlier. [edit] --------------------------- |
Evert
Member #794
November 2000
![]() |
Quote:
speed += dt * acceleration; Slightly more physically correct would be position += dt * speed + 0.5 * acceleration * dt*dt; speed += dt * acceleration; to take into account that the velocity is not a constant during the integration. The error by neglecting this is O(dt^2), so it is negligible if dt is small enough (and maybe negligible for in general for the purpose of computer games). |
Thomas Harte
Member #33
April 2000
![]() |
Quote: Oh, and personally, I use a high frequency timer to calculate dt accurately for every frame, instead of relying on FPS. This is close to what I do, but I find that high frequency timers are very unreliable in Allegro that relying on anything over about 100bps being portable isn't smart. Hence I average a small number of frames (3 in the thing I'm writing for the ray casting competition) to remove any sudden lurches. Of course, normally I program in SDL where SDL_GetTicks() does the business for me in a much more predictable fashion and without the processing overhead of an extra thread! [My site] [Tetrominoes] |
Jakub Wasilewski
Member #3,653
June 2003
![]() |
Thomas Harte said: This is close to what I do, but I find that high frequency timers are very unreliable in Allegro that relying on anything over about 100bps being portable isn't smart.
I don't use Allegro timers Maybe we could implement an interface for those high resolution clocks in Allegro itself? Perhaps al_get_ticks(), al_get_ticks_per_sec()? --------------------------- |
Thomas Harte
Member #33
April 2000
![]() |
Quote: (I hope that'll work for Macs too) I built and ran the following under OS X v10.4.1, gcc 4.0: #include <sys/time.h> ... int c = 2000; while(c--) { struct timeval t; gettimeofday(&t, NULL); printf("%d:%d\n", t.tv_sec, t.tv_usec); } And got the output: Quote:
1116788235:919471 So it should be good! Quote: Maybe we could implement an interface for those high resolution clocks in Allegro itself? I would strongly support this, but the traditional line from Allegro developers has been "we don't need that we have timers" and "timers are good enough - the developer should always be making a fixed number of discrete logic steps per second". So I won't hold my breath. [My site] [Tetrominoes] |
Fladimir da Gorf
Member #1,565
October 2001
![]() |
I really don't like it how even the Allegro's docs recommend to limit the frame rate to a specific number. Tell me, how many commercial games do that nowadays? None. Zero. Null. So why would the Allegro developers do that then? Maybe because Allegro is considered as a newbie library and copy-pasting a few lines from the manual sounds like the best solution, huh? I'd say the delta time syste is, in fact, much easier to understand for new programmers than the strange increasements and decreasements. Most of us have learned some physics, right? OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori) |
Richard Phipps
Member #1,632
November 2001
![]() |
Quote: Most of us have learned some physics, right? None at all I'm afraid. The existing frame method is good for some games and bad for others, the same as for the delta time system. Use what works best for each game. |
Evert
Member #794
November 2000
![]() |
Quote: Maybe we could implement an interface for those high resolution clocks in Allegro itself? Makes sense, at least for discussion post 4.2. Quote: I really don't like it how even the Allegro's docs recommend to limit the frame rate to a specific number. [...] So why would the Allegro developers do that then?
Because they have a lot of things to do and making substantial changes to the docs takes a tremendous amount of time - especially if it's something that can be argued pro and con. |
|