Reputation: 2540
As far as I understand, there's a pretty standard way to implement gravity, which is pretty much the real deal; adding a number (say, 9.8) to an object's downward vertical velocity with each time step.
However, this simple math has led to an issue of "infinite bounce" in my program (and apparently others). The simple test case so far has a ball dropping straight down, and hitting the "floor". On collision, the ball's vector is deflected and reduced by 1/4 (a placeholder Coefficient of restitution). On every time step, the gravity value (around 2 in my case) is added to the vector. As a result, the ball bounces, and then bounces lower, and lower... and then instead of truly stopping, or even visibly stopping (the real goal), it jitters up and down on the bottom of the screen. Debugging readouts show that its speed never drops below 2 for more than a couple frames, because that constant just keeps getting added and cancelled and added again indefinitely.
Now, understanding why isn't the hard part. It's exactly what I feared from the start, I just figured there was some mathematical magic I was overlooking since no one ever actually mentions such an issue when explaining the math. But - since no one ever discusses it - that does leave me wondering, what is the "typical" way to go about fixing it?
EDIT: After considerable work, I have determined that using separate acceleration values alone won't fix the problem - it will still always try to add some constant fraction of gravity. Constant time step means constant acceleration; constant acceleration means constant velocity increase. The coefficient of restitution on bounce will cause the velocity to reduce to a point, and negate acceleration, but acceleration will start over from 0. Like so:
Now, the overall problem is not that velocity will never equal 0. That is expected. But what is also expected, is an infinitely decreasing number. With a Coefficient of Restitution set at 0.5, the resulting bounce velocity should be half that of the last, progressively decreasing until it can be discarded as "stopped". By introducing pure constant addition - be it adding directly to velocity, or adding it to another value that gets added to velocity - this problem is incurred. I need to know how to solve that, specifically.
Upvotes: 4
Views: 2243
Reputation: 6202
Just dealt with the same problem.
Here is the code that fixed it for me:
if (cat.y + cat.height >= ground.y) // if the cat has hit the ground
{
cat.y = ground.y - cat.height; // reset to the bottom
cat.vector.y = Math.round(COR * -cat.vector.y); // might want to round down
}
The important part here is the rounding.
Upvotes: 1
Reputation: 909
To solve it the only thing you have to do is when the ball hits the ground reverse the vertical velocity and place the ball on the barrier so that the ball will lock on to the ground because the 9.8 / 4 upwards velocity won't be enough to 'unlock' it and set it in another bounce.
Upvotes: 0