This works because dt is in seconds and VEL is in meters per seconds.
This doesn't look right.
In Box2D, applyForce works with Newtons where the formula is f = mA
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.