I can see why you think that, however…
The problem is that you are compounding the velocity.
If, for example, velocity
is -1
then after velocity += (velocity * accelerationModifier)
it will be -1 + -1 * 0.03
, which is -1.03
. Next frame it will be -1.03 + -1.03 * 0.03
, which is -1.0609
.
Every frame the velocity will increase, at first it will be a small increase but eventually the velocity becomes large enough that it hits a point where the gravity doesn’t do enough to counteract it and your ball just keeps flying into space.
The bottom line: you are constantly accelerating the ball and it never stops increasing.
If you take away the so-called ‘acceleration modifier’, the problem becomes worse because you’re going from doing what is effectively velocity *= 1.03
to velocity *= 2
(velocity += velocity
is equivalent to velocity *= 2
).
I think perhaps you misunderstand the point of acceleration, so it’s time for a little physics lesson to clear things up…
In the real world acceleration isn’t a constant force, acceleration is the result of a force acting on an object.
A force, such as gravity, is applied to an object and that causes the object to accelerate.
The acceleration increases the object’s velocity and the object’s velocity is what causes the object to move.
If there’s no force, there’s no acceleration or decceleration, as would be the case in a vacuum.
On earth you have forces like gravity, friction, and air resistance that force an object to gradually come to a halt by deccelerating them or causing them to accelerate towards the Earth’s core until they hit another solid object (typically the ground).
Properly speaking the way acceleration is supposed to work is more like:
// Calculate the acceleration as the sum
// of all the forces that are acting on the object,
// including gravity.
object.acceleration = calculate();
object.velocity += object.acceleration;
object.position += object.velocity;
Sometimes for game physics it’s alright to take shortcuts, like skipping over acceleration and just doing velocity, which is what I did in my Physix demo.
With that in mind, let’s look back at your code for a moment.
If you comment out the this->ball.yVelocity += (this->ball.yVelocity * this->physics.accelerationModifier);
line, suddenly things become a lot more stable. It doesn’t achieve quite what you’re hoping for because it produces a system with no loss of energy, but it behaves more appropriately because the ball is no longer accelerating infinitely.
With that you’re almost there. However there’s another subtle bug in your code that causes the ball to gradually bounce higher. The fact you apply the gravity after moving the ball actually causes the physics to behave improperly. You might think it shouldn’t make a difference, but it actually causes the position and velocity to be unsynchronised, and that subtle difference is enough to cause the velocity to steadily increase instead of steadily decrease.
One way to think of it is that you end up applying an extra step of gravity before the bounce happens, so when the velocity inverts it ends up having more velocity than it should have.
Another way to think of it is that forces are a means of transferring energy, so by applying more gravity than should be being applied prior to the bounce you’re causing the bounce to provide more energy than it should have, which causes an imbalance.
Under real world conditions a bounce wouldn’t be a perfect inversion anyway, there should be some loss of energy as a result of the collision (the ‘restitution’ mentioned by @brow1067). Sometimes it’s fine to ignore this in games if you aren’t too worried about accuracy, as long as the end result still provides the same effect, which is the case after fixing the gravity bug.
Anyway, with the gravity fixed and the acceleration removed you end up with code that does more or less what you intend. It leaves you one more issue though, because of the way you’re handling the collision. You’re actually waiting for the ball to go through the trampoline before making it bounce when what you really want to do is to detect the collision before an intersection occurs.
To figure that out, I recommend having a look at the updateEntityPosition
function from my Platformer Demo.
At any rate, hopefully this helps you see why your code is going so far awry:
- Your acceleration based on the velocity when it should be the other way around.
- You’re constantly applying velocity when it should only apply if there are forces (such as gravity and bounce) acting on the ball.
- Your application of gravity and updating of position are reversed, which ends up producing extra energy from nowhere.
It doesn’t matter if you do it accurately or simulate it in an inaccurate way, but the system still needs to follow the same general rules to achieve the same effect as real world physics.
There’s a few redundancies in your code that could be rectified, but I’ll leave that there for now because this has been a long comment and I think I should give you chance to take it all in, think it through, and formulate a response before I bombard you with anything else.
You can see the mentioned changes along with a simplification of your bounce code here:
Recommended reading/watching in regards to physics and vectors: