Although this looks like a write-up at first, it''s really a question but it needs to be specific. Excuse the length of the post...
A lot of game demos that show the use of gravity will simply invert an objects y-axis velocity when the object hits the "ground" if they want it to bounce back up...
#define PIXELS_PER_METER 300
#define GRAVITY (9.8 * PIXELS_PER_METER) / 100
#define APPROX_GRAVITY (10 * PIXELS_PER_METER) / 100
object.y += object.vy;
if(object.y + object.height > screen_height)
{
object.y = screen_height - object.height;
object.vy = -object.vy;
}
object.vy += APPROX_GRAVITY * last_frame_time;
This is all fine and good (and usually best) for most situations, but in terms of more realistic physics simulation I see this as incorrect for three reasons.
One, in real life, an object hits the ground and bounces back up. In the code situation the object falls into the ground, is instantly repositioned at ground level, and then is bounced back up.
Two, the code example assumes perfect elasticity (not too big of a deal) so, when the object is bounced back up, it goes back in the "air" with the same energy it hit the ground with.
Three, because the object was repositioned and restitution isn''t taken into consideration, the object should actually going back in the air with MORE energy than what it hit the ground with.
It adding restitution is easy, simply "absorb" some of the energy of the object when it hits the ground...
object.cor = .92; // coefficient of restitution (bounciness)
/*
... some code here ...
*/
object.vy = -object.vy * object.cor;
So that takes care of number 2 and part of number 3. Now, to adjust the object''s energy so it hits the ground instead of falling into the ground, the objects velocity needs to be adjusted to negate the extra energy it gained while falling into the ground. To do this some information is needed... the objects current velocity (object.vy), its speed of acceleration (APPROX_GRAVITY * last_frame_time), and the distance the object fell into the ground (object.y + object.height - screen_height).
Here is where I''m sure I messed up my calculations...
To calculate the extra velocity gained while falling into the ground, I used the kinematic equation for velocity after acceleration over a distance...
Vfinal^2 = Vinitial^2 + 2*Acceleration * Distance
float
vf, // Vfinal
va, // Vadjusted
vi, // Vinitial
accel, dist;
vi = object.vy * object.cor;
accel = GRAVITY;
dist = (object.y + object.height) - screen_height;
vf = sqrt((vi*vi) + 2 * accel + dist);
va = vf - (vf - vi);
object.vy = -va;
object.y = screen_height - object.height;
While this seems correct at the moment, when the energy of the object gets extremely low, the energy from the bouncing and gravity begins to fluctuate (the object''s energy never gets low enough that it stops "dribbling"). Right now I''m attributing this to either not enough accuracy in the gravity constant or timer (GetTickCount()), or to an error in the calculation. Any ideas?
This shouldn''t be hard to turn into real code but if someone feels the actual source code is needed, I can make it available.