pouët.net

Frame-independent movement, I'm stuck

category: general [glöplog]
(vNorm is probably (0,1,0) in the case of your game (i.e. the normals of your 2D platforms simply point "up").
"vIn" is the "incoming" vector and "vReflect" receives the resulting reflection vector)
added on the 2009-01-02 01:41:32 by xyz xyz
..and "dot" = (x*other->x + y*other->y + z*other->z)
in case you're wondering
added on the 2009-01-02 01:49:15 by xyz xyz
god, so much vector stuff.... I'll need to take a nap first. :P
\o
blala has leading - calculate fixed time steps correctly with a resolution that youÄre deeming high enough for gameplay, then, just for displaying, interpolate linearly between the current and the last step according to the fraction.

If that looks awkward on sudden velocity changes or position jumps (ball hits platform, camera skips to somewhere else, etc), introduce a flag that skips interpolating and uses just the current step's values.
added on the 2009-01-02 01:53:54 by kb_ kb_
basically you're right, kb.

you can't just skip "n" frames of collision detection w/o changing the gameplay.
Personally, I like to lock my games in to "60 FPS vsync" and simply offer to change the render parameters to make it run on slow machines.

arcade is 50/60fps anyway, is it :) ?
added on the 2009-01-02 01:59:04 by xyz xyz
Quote:
Accelaration = constant;
velocity+=Accelration *deltaT;
position+=velocity*deltaT;


That's only a crude approximation. For calculating the new position you assume that the velocity is constant over the timestep. With constant acceleration you get linear velocity, so it does work for any timestep, but not if you use the velocity at the beginning or end of the timestep. You need the mean velocity:

Code:1) v0 = v 2) v += a * dt; 3) x += (v0 + v) / 2 * dt


Or, alternatively:

Code:1) x += v * dt + a * dt^2 / 2 2) v += a * dt
added on the 2009-01-02 13:04:59 by doomdoom doomdoom
Variable timesteps are a bitch to work with, but a framerate that doesn't match the monitor's refresh rate gives you ugly, stuttering graphics. Running your game engine at a fixed framerate and your rendering engine at a different framerate gives you threading complications and (worse) another layer that adds latency. You may not be able to get the interpolation looking right, either, unless the game engine is running at a framerate higher than or equal to the rendering engine, which means you'll have to aim for something like 100 FPS.

Console developers have it all too easy. :)
added on the 2009-01-02 13:22:10 by doomdoom doomdoom
I had an issue similar to this doing some NDS development. The system didn't have any timers that were high enough resolution to calculate the time elapsed since the last physics calculation, and DMA transfers seemed to affect the hardware timers, which made everything behave all crazy. Eventually I just used the vsync interrupt to increment my own counter (which counted 60ths of a second), and deferred physics calculations if the counter had not changed since last time. This works very well.
added on the 2009-01-02 13:36:13 by Claw Claw
Insectecutor, that sounds very nice of course, but relying on the vsync on a pc system is not very reliable, i fear. especially since I won't force a special refresh rate. I just had an idea about integration last night, maybe I should try that again before I try to understand those complicated formulas :P
That's a nice little article there. And he's probably right that a fixed timestep is the only practical way to do physics in games. The problem you can't get around, though, is that you need to aim for a fairly high simulation framerate, and the game speed is limited by the time it takes to perform the simulation. So if the hardware is too slow for the simulation at the timestep you've chosen the game won't be able to run as intended anyway. Plus, this innocent-looking line is not so innocent if the game state is a large data set:

Code:previousState = currentState;


But I guess most physics engines use some form of doublebuffering anyway.
added on the 2009-01-02 14:10:44 by doomdoom doomdoom
Quote:
Plus, this innocent-looking line is not so innocent if the game state is a large data set:

huh? We have intricate enginereed solutions, like, uh, pointers, to solve that... Not that memory bandwidth would be a big problem these days for the physics state.

The be ontopic, the article suggests exactly what was said above.
added on the 2009-01-02 15:03:22 by blala blala
The formula we learned at school ("free-fall") was:
Code:y(t) = y(0) + g / 2 * t^2

For g = 5 and y(0) = 1, this would give:
Code:t y(t) 0 1 1 3.5 2 11 3 23.5

And you could insert any value for t, including 1.25.
added on the 2009-01-02 15:07:18 by Adok Adok
that's when your physics engine operates in a vacuum!
True. Here is a formula for free-fall with air resistance. But he didn't ask for it.
http://de.wikipedia.org/wiki/Freier_Fall#Fall_mit_Luftwiderstand:_Newton-Reibung_FR_.3D_kv2
added on the 2009-01-02 15:22:45 by Adok Adok
i thought that this should do it, but it's a slightly different result. it may work, actually. (Yes, it's fucking freebasic, I know that I suck)
Code: Dim As Double dummy = frameduration While dummy > 0 If dummy < 0 Then vy += gravity * dummy y -= vy / velocity_ratio_y Else vy += gravity y -= vy / velocity_ratio_y EndIf dummy -= 1 Wend
eh, no. Your first if block will never be taken because the line directly in front of it ensured "dummy>0".

Really, listen to blala, me and the gafferongames article above. And DON'T listen to people saying we're wrong and that therefore physics that stutter or are hardware dependant are ok. :)
added on the 2009-01-02 16:10:53 by kb_ kb_
Oh, that should be if(dummy < 1) ... i was half-asleep when i wrote that down. I wanted to calculate the physics at a constant framerate of course, but it simply does not seem to work with the timer resoluation that I get from windows and linux.
i do disagree with a separate physics thread though
added on the 2009-01-02 16:16:58 by Gargaj Gargaj
all i need now is a really _reliable_ timer, because the code that I posted above also doesn't work anymore with a very long or very short sleep(). On the other hand, always calling a sleep(10); does not work either, because it has a different length as soon as BASS is initalized.

this is killing me :(
Wtf is wrong with "QueryPerformanceCounter" for Windoof or "gettimeofday" for Linux?
added on the 2009-01-02 17:14:54 by raer raer
If nothing helps, I'll have to look into those, thanks...
Or GetTickCount() ?
added on the 2009-01-02 17:40:54 by Adok Adok
Give me the equivalent on linux, kthx.
Saga Musix: BTW, what you described in your first posting is Euler integration, which is also explained in this article. The article also explains why it's not so good and what you should use instead.
added on the 2009-01-02 17:46:43 by Adok Adok

login