Physics-Based Bounce Effect - Page 4
       by kirupa  |  10 February 2009

In the previous page, you saw what it takes to make your ball fall. That is only half the story. In this page, let's look at what it takes to cause the fallen ball to rise back up.

The Ball is Rising
Let's continue looking at the code from where we left off...starting with the startRisingBall method:


// Sets up what is needed to start bouncing the ball up
function startRisingBall() {
initialSpeed=decay*Math.sqrt(2*Math.abs(finalPos-initialPos));
timer=0;
currentPos=this.y;
this.addEventListener(Event.ENTER_FRAME, moveBallUp);
}

The startRisingBall method is responsible for taking your ball from the bottom and moving it to the top. Like I explained a few pages ago, the speed your ball has as your bouncing up is exactly the same speed it had when it fell to the ground. The equation for that is what you saw earlier:

Because of conservation of energy, if the same speed was used, that would mean your ball would be bouncing indefinitely, so I introduce a decay value that I briefly talked about to dampen the speed a bit. Putting it all together, you get the following line of code:

initialSpeed=decay*Math.sqrt(2*Math.abs(finalPos-initialPos));

The final deed the startRisingBall method does is just resetting some of our variables to start the ball moving up. Because I am treating the up movement as a separate, independent action, I reset my timer and currentPos to 0 and my ball's current position respectively.

The final thing this method does is set up the animation by registering the ENTER_FRAME event with the moveBallUp event handler...which we'll look at next.


// Responsible for moving the ball up
function moveBallUp(e:Event) {
timer+=1;
 
//Storing the position of the ball before and after it moves
var positionA:Number=this.y;
this.y = currentPos - initialSpeed*timer + .5*gravity*(timer * timer);
var positionB=this.y;
 
checkTopBoundary(positionA, positionB);
}

The moveBallUp event is the arch-nemesis of your moveBallDown method. This method gets called at each ENTER_FRAME event, and it is responsible for moving the ball up. It does this by first incrementing the timer and then setting the current position to our favorite equation for position:

The line of code mapping to the above diagram is:

this.y = currentPos - initialSpeed*timer + .5*gravity*(timer * timer);

The only difference now is that the initialSpeed actually matters. That is why it is visible in the code whereas it was omitted in its counterpart for making the ball fall earlier.

The last thing is to make a call to the checkTopBoundary method that takes positionA and positionB as arguments. Notice that the positionA and positionB variables measure the position of the ball before and after it gets moved. While this sounds odd, I am doing this to figure out whether the ball is still moving up or whether the ball's direction has changed.


// Checks when the ball has hit the top of the bounce
function checkTopBoundary(firstPos:Number, secondPos:Number) {
if (secondPos>firstPos) {
stopRisingBall();
startFallingBall();
}
}

While I gave some of details away in the preceding section, I check the direction of the ball movement in the checkTopBoundary method. The reason is that, if I didn't check the direction, the ball would automatically reverse direction and start moving down. I already have code dedicated to making the ball fall! You spent an entire page looking it. Instead, by comparing whether the secondPos is greater than the firstPos, I can stop the current animation and switch to all of the code you saw before for making the ball fall.

If the second position is greater than the first position, I immediately call both the stopRisingBall and startFallingBall methods! As their names apply, one method stops the ball from rising, and the other method starts the ball falling. Phew. You are almost done. Let's just jump back up in our code to look at the variables you have declared.


var timer:Number=0;
var initialPos:Number=0;
var finalPos:Number=0;
var currentPos:Number=0;
var initialSpeed:Number=0;
var startPosition:Number=0;
var gravity:Number = 1;
 
//Adjust this to increase or decrease the
//number of bounces
var decay:Number = .9;

The variables at the vary top help keep track of the various things that help your ball either fall or bounce. The most important variable is the one for decay. This decay variable is used to dampen the bounce each time your ball hits the ground. A really small value for decay means that the bouncing will stop very quickly. A larger value (such as .95 or .99) indicates that the bounce will go on a bit longer. A value of 1 means the bouncing will continue indefinitely. This would be the ideal case where energy is perfectly conserved.

Conclusion
I hope you found this tutorial useful. While the end result was a look at the code that is responsible for making something bounce, I think the more important part is understanding the physics behind why the code is written the way it does. Best of all, I probably brought back fond memories of you having seen some of these concepts in your classes in the real world!

Just a final word before we wrap up. If you have a question and/or want to be part of a friendly, collaborative community of over 220k other developers like yourself, post on the forums for a quick response!

Kirupa's signature!

1 | 2 | 3 | 4




SUPPORTERS:

kirupa.com's fast and reliable hosting provided by Media Temple.