Reputation: 1279
I am writing a physics engine and when the ball hits a surface it bounces up at half the velocity it came down at(velocity.y = -velocity). However when the ball is almost at rest it switches velocities constantly and starts falling through the platform incredibly slow but still will eventually fall through if I let it run long enough, and this is not acceptable. I tried writing some code to stop it but it checks way too fast here is the update method that attempts to check it.
public void update() {
velocity.y += Globals.GRAVITY.y;
if(canFall)
position.y += velocity.y;
position.x += velocity.x;
oldPosition.y = position.y;
oldPosition.x = position.x;
elapsedTime += 1 * Gdx.graphics.getDeltaTime();
if(elapsedTime >= 5){
if(oldPosition.y - 5 <= position.y && oldPosition.y + 5 >= position.y){
elapsedTime = 0;
canFall = false;
}else{
canFall = true;
elapsedTime = 0;
}
}
}
The collision handler knows when it hits the top of the ball which is the only solution I need for this. How do I check when the ball is at rest.
This code attempts to check if the ball hasn't moved in a couple seconds, if it hasn't it sets canFall
to false
. I need a generic check that will see if the ball should be at a stop. The velocity of the ball when it is falling through the platform you can see from the picture below. The picture shows the ball "at rest" after ten seconds so as you can see the ball is slowly but surely falling through. Every three seconds with this "rest" velocity the y position goes down 1, the velocity changes from positive to negative so the velocity you see in the picture isn't constantly negative. Ignore the elapsed time variable Any help is greatly appreciated!
Upvotes: 2
Views: 134
Reputation: 4283
Why let time have anything to do with it? I'm not saying it coudln't, but should it? So maybe lose the if(elapsedTime ... )
conditional.
Isn't this what you want? If the magnitiude of the vertical difference between the last two positions is negligible (set tolerance
accordingly; maybe it's 5), stop bouncing:
if(Math.abs(position.y - oldPosition.y) < tolerance)
{
canBounce = false;
...
}
else
{
canBounce = true;
...
}
or, if nothing else needs to change at the ...
above:
canBounce = Math.abs(position.y - oldPosition.y) > tolerance;
Also, don't you need {
and }
somewhere in the segment below? Maybe not, if ball is bouncing vertically, but it looks like x
can change, too, which might make the code above need adjusting. But the way code below is indented makes me think there's supposed to be more to do than just changing position.y
:
if(canFall)
position.y += velocity.y;
position.x += velocity.x;
oldPosition.y = position.y;
oldPosition.x = position.x;
Finally, you're addding velocity to position. That seems questionable. Multiply velocity times time? Or is time = 1 always? (Doubt it.)
The problem may be external to this method. Something needs to keep ball's y
from becoming less than the y
of the top of the dark blue box. This code can't do that without knowing y
of top of dark blue box (unless you apply physics formulas?). Maybe include this value in parameter list as topOfDarkBlueBox
?
Then add code such as:
if(position.y < topOfDarkBlueBox.y) position.y = topOfDarkBlueBox.y
I'd rather see physics at work, but you might say, "Who'd notice?"
EDIT
You wrote, "The collision handler knows when it hits the top of the ball," but I assume you meant "when the ball hits the top of the dark blue box". Maybe call the collision handler instead of passing new parameter topOfDarkBlueBox
?
Upvotes: 1