-
Simple Bouncing Logic
Hello,
I wonder if someone could give me a quick hand with the logic for an simple falling object that bounces inelastically, that is, it doesn't bounce back to the same height as before and will reach a point of rest. It's for a general 2D game object framework thingy that I fancied having a go at doing.
Anyway, here's what I've got so far:-
Code:
tt = me->pvData; // get our pointer to extra info for this type
if (tt->dVelocity != 0)
{
// We're on the move
if (fabs(tt->dVelocity) < 0.1)
{
// Below minimum clout, if there's something below stop
if (DetectRect(me, me->x, me->y + 1, me->w, me->h))
tt->dVelocity = 0;
}
else
{
// Keep going
tt->dVelocity += GRAVITY * 0.02; // 1/60 second
me->y += (tt->dVelocity - (int)tt->dVelocity >= 0.5) ? (int)tt->dVelocity + 1 : (int)tt->dVelocity;
}
}
else
{
// We're stopped. If there's nothing holding us up...
if (!DetectRect(me, me->x, me->y + 1, me->w, me->h))
{
tt->dVelocity += GRAVITY * 0.02;
me->y += (tt->dVelocity - (int)tt->dVelocity >= 0.5) ? (int)tt->dVelocity + 1 : (int)tt->dVelocity;
}
}
So far the object bounces once and then stops. When it collides with another object the velocity is inverted, like so:-
Code:
tt->dVelocity = -tt->dVelocity * tt->dVelScale;
tt->dVelScale += 0.1; // try to give a ping-pong ball effect (retains more energy the closer it is to rest)
Using dVelScale like that is probably not the best way to achieve what I want, but I want to use a simple model, people can adjust this value to give different effects.
Can anyone describe how I can best check if the object needs to start/stop moving?
-
My physics book gives the following formula for the coefficient of restitution, which measures how elastic the collision is:
e = - ( v1+ - v2+ ) / ( v1- - v2- )
Where vn+ are the velocities of the two objects after and vn- before the collision. e = 0 means totally inelastic, e = 1 means totally elastic.
And I just realized this has little to do with your question. But it might help you to make the collision more realistic.
-
Nono, I think it helps, I was actually looking at Wikipedia a few minutes after posting this at the COR and thinking "Ohhhhhhh...". :o
I think it's a good idea to implement that into my "simple" model. The main point is just whether anyone else has had to deal with the possibility of something bouncing on a possibly moving object. I'm not after calculating normals, that'll come a bit later, just the best way to toggle between falling and not falling. ;)
EDIT: Now it looks like:-
Code:
tt = me->pvData;
if (tt->dVelocity > 0 && tt->dVelocity < 0.01) // Only check if we're falling (positive velocity)
{
if (DetectRect(me, me->x, me->y + 1, me->w, me->h))
tt->dVelocity = 0;
else
{
tt->dVelocity += GRAVITY * 0.02;
me->y += (tt->dVelocity - (int)tt->dVelocity >= 0.5) ? (int)tt->dVelocity + 1 : (int)tt->dVelocity;
}
}
else
{
tt->dVelocity += GRAVITY * 0.02;
me->y += (tt->dVelocity - (int)tt->dVelocity >= 0.5) ? (int)tt->dVelocity + 1 : (int)tt->dVelocity;
}
and
Code:
// This body's mass = 10, COR = 0.8. Other body's mass = 2, velocity = 0.
tt->dVelocity = (tt->dVelocity * (tt->dMass - (tt->dRestitution * 2))) / (tt->dMass + 2);
tt->dVelocity = -tt->dVelocity; // Er... bounce?
-
You will have to integrate that in order to simulate the bouncing on a per-frame basis.
-
Not sure what you mean, Bubba. The larger block of code is called with the game loop (60 Hz), so acceleration due to gravity is simulated OK. The smaller block is called whenever a collision between the falling object and something else is detected, this should be an instantaneous calculation surely? :confused:
Watching the object's velocity before and after a collision, using the same object parameters as before (positive = down):-
6.120000 -> -2.972571
3.327429 -> -1.616180
2.703820 -> -1.313284
2.646716 -> -1.285548
2.674452 -> -1.299020
2.480980 -> -1.205048
2.574952 -> -1.250691
2.709309 -> -1.315950
2.644050 -> -1.284253
2.675747 -> -1.299649
It seems to oscillate...