About FPS and dt

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
fede0d
Prole
Posts: 5
Joined: Sat Dec 14, 2013 4:01 pm

About FPS and dt

Post by fede0d »

Hello everybody. I have some questions about FPS and dt not only on LOVE but on game programming on general.
If I want to move something on the screen and keep constant speed no matter what FPS the game is running on, I have to use something like this:

Code: Select all

x = x + VEL*dt;
Here, if FPS is high dt tends to 0, so VEL*dt is low and tends to 0 (I have to move less on each frame).
On the contrary if FPS is low dt tends to 1, so VEL*dt tends to VEL (I move more on each frame compared to low FPS)

This works ok if I move things by myself. But if I need to apply force on a body in a physics simulation this doesn't work.
I figured out I needed to use:

Code: Select all

applyForce(VEL * (1-dt));
If FPS is high, on each frame I apply more force. And if FPS is low I apply less force on each frame. This seems contradictory, but it works. And I don't know why!
I guess it's something related to the physics simulation, the friction of the body and other things.

Do you know why this is this way? I'm I doing something wrong? How do you manage these things?
bekey
Party member
Posts: 255
Joined: Tue Sep 03, 2013 6:27 pm

[]

Post by bekey »

-snip-
Last edited by bekey on Fri Jan 24, 2014 1:38 am, edited 2 times in total.
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: About FPS and dt

Post by ivan »

Code: Select all

x = x + VEL*dt;
This works because dt is in seconds and VEL is in meters per seconds.

Code: Select all

applyForce(VEL * (1-dt));
This doesn't look right.
In Box2D, applyForce works with Newtons where the formula is f = mA

Code: Select all

force = mass*acceleration
Where the acceleration = (V2 - V1)/dt

Code: Select all

acceleration = (desired velocity - current velocity)/dt
So your code might look something like:

Code: Select all

-- find the acceleration required to reach a desired velocity
local vx, vy = body:getLinearVelocity()
local cVel = math.sqrt(vx*vx + vy*vy) -- current velocity
local dVel = DESIRED_VELOCITY -- desired velocity
local accel = (dVec - cVel)/dt -- acceleration
-- get the force vector
local mass = body:getMass()
local force = accel*mass
local fx = vx/cVel * force
local fy = vy/cVel * force
applyForceToCenter(body, fx, fy)
This should make your body move at a constant speed which is OK but it's not very realistic.
It is similar to setLinearVelocity except that it won't override the effects of gravity and collisions with other bodies.
The problem with the code I wrote above is that the acceleration of the body can vary A LOT.
Usually, the acceleration should be clamped to a certain value so that your bodies accelerate and decelerate GRADUALLY:

Code: Select all

accel = math.max(accel, -MAX_ACCELERATION)
accel = math.min(accel, MAX_ACCELERATION)
Or you can clamp the "force" variable if you want heavier objects to accelerate slower.
Also, keep in mind that Box2D should be updated with a constant time step to avoid wild behavior in joints; to avoid tunneling and overlap with stacked bodies.
fede0d
Prole
Posts: 5
Joined: Sat Dec 14, 2013 4:01 pm

Re: About FPS and dt

Post by fede0d »

Thanks guys! This helped me a lot.
Post Reply

Who is online

Users browsing this forum: Google [Bot], YaCy [Bot] and 3 guests