This is still Euler integration, which has poor accuracy whenever the derivative varies with time. The standard numerical integration method is 4th order Runge Kutta. RK4 is also popular for solving many forms of differential equations.<p>A good summary is here: <a href="http://gafferongames.com/game-physics/integration-basics/" rel="nofollow">http://gafferongames.com/game-physics/integration-basics/</a>
you are still doing it wrong. dt should not be affected by framerate.
<a href="http://gafferongames.com/game-physics/fix-your-timestep/" rel="nofollow">http://gafferongames.com/game-physics/fix-your-timestep/</a><p>use an accumulator to have a fixed dt no matter the framerate. With a variable step size you risk all kinds of weird bugs linked to the hard to debug rendering context. The size of dt should be consider a system parameter, tuned for your game and <i></i>fixed in concrete<i></i>.
This is still basically wrong for general game physics. I.e. you should <i>not</i> blindly follow the author's suggestion to use it for all forces.<p>It <i>happens</i> to be an exact solution for one very specific situation -- the case of a constant force that is always applied. In this case, unvarying gravity with no air resistance.<p>This is typically one of the first things you learn in a Classical Mechanics course, because they can teach it using just Kinematics (the definitions of displacement, velocity, and acceleration) before introducing Dynamics (forces).<p>To prove it, you can just integrate the definition of acceleration twice and recognize that the integration constants are your initial position and velocity.<p>If the time-step changes or if forces are due to input, or other changing factors then this is still a pretty terrible method.<p>Ah ... I should clarify ... the method is not so terrible, but rather the author's explanation and rationale are. Basically, it slightly improves on one little piece of the puzzle, and completely ignores the real issues like fixed time steps, render/physics/network/game logic loop decoupling, and stiff systems.<p>FWIW, I shipped two hit games this year that only used Euler integration and worse hacks. It made life painful, though.
Udacity has a course, "Differential Equations in Action", that's about numerical solutions of equations of motion and other differential equations from physics, biology, and so on. <a href="http://www.udacity.com/overview/Course/cs222/CourseRev/1" rel="nofollow">http://www.udacity.com/overview/Course/cs222/CourseRev/1</a>
For other simple methods of numerical integration, look at the Trapezoidal Rule and Simpson's Rule, two staples of high school (or college) calculus.<p>Since we're talking about gaming, it bears noting that Box2D (and most physics engines, for that matter) uses the Semi-implicit Euler method (<a href="http://en.wikipedia.org/wiki/Symplectic_Euler_method" rel="nofollow">http://en.wikipedia.org/wiki/Symplectic_Euler_method</a>). The author of Box2D mentions that this is a better method than Verlet integration because calculating friction requires knowing velocity.
This same thing is used in molecular dynamics simulations. For instance, there is an algorithm called RESPA that is used to break integrations of different types of particle interactions into appropriate timestep intervals. Bond vibrations must be calculated much more frequently than non-bonded interactions.<p>The algorithm (reversible RESPA) is formally derived from the Liouville operator (which governs the time evolution of any property):<p><pre><code> A(t) = exp(iLt) * A(0)
</code></pre>
For instance, A(t) can be position or momentum. The Liouville operator must be symmetric in order to generate a reversible numerical integration algorithm.<p>The result of all this is basically that:<p><pre><code> p(t + ∆t/2) = p(t) + ∆t/2 F(r(t))
r(t + ∆t) = r(t) + ∆t p(t + ∆t/2)
p(t + ∆t) = p(t + ∆t/2) + ∆t/2 F(r, t + ∆t)
</code></pre>
where p is momentum, r is position, and F is force.
This is known as the midpoint method.<p><a href="http://en.wikipedia.org/wiki/Midpoint_method" rel="nofollow">http://en.wikipedia.org/wiki/Midpoint_method</a>
It's an interesting post, but perhaps a simpler way of looking at the whole thing is you should be using average velocity over the time elapsed rather than the just-calculated new velocity.<p>This becomes:<p>velocity_new = velocity_old + acceleration * time_elapsed<p>position_new = position_old + (velocity_old + velocity_new) * 0.5 * time_elapsed<p>It makes immediate, intuitive sense (at least it does to me) and doesn't require even thinking about differential equations (at least for constant forces).
His improved graph actually still doesn't hit the peak at all frame rates. The right way to do things from the usability perspective would be the calculate the peak and make sure the player can hit exactly that at some point. Otherwise areas that are supposed to be reachable may not be, as he says. The code for that wold be a lot more complex, though, so it may be the wrong thing from a business perspective, spending large amounts of your dev time on a small edge case of users and user situations.
You can cut down the amount of error even further by not iterating. Instead of iteratively updating the height, just store the initial position, velocity and time. You still compute the current position as pi + vi * dt - a * dt * dt/2, but intermediate results are discarded to avoid compounding floating point errors.<p>Of course, you will need to update the initial position/velocity/time whenever the jump is interrupted or modified. The reduction in error is also quite small.
Why does this even matter? If you have a large delta time then your game is fucked anyway. Collision detection will likely also be broken and the game is unplayably choppy anyway so it doesn't even matter.
There are several ways to do "game gravity right" and not just one answer.<p>For example some games have entirely reproducible game states which depends on only two things: the seed given to the PRNG and the inputs made the player (and the time at which they happened).<p>There are a lot of games (probably most of them) which have gravity but which aren't "real" physics simulation and/or which do definitely not need a "real" physics simulation to be, well, fun games.<p>Some of them do simply use integer-math and precomputed "gravity lookup tables" entirely consisting of integers. You then use the time elapsed to know where you should look in your table and you can of course compute a value "between two lookup indices".<p>The advantage of integer math (either using gravity lookup table or not), compared to floating-point math, is that your game engine can stay deterministic even if the floating-point numbers implementation vary from one platform / virtual machine to the other.