How do I reduce the bounce height of a bouncing ball after every bounce

I’d like to know how I can make a ball bounce with reduced height over time no matter where the ball is initially positioned (y = 100, or y = 200, or y = 250 etc).

From the code below which you can simply put into main.lua and run, you’ll notice the ball starts in the air (y = 300), falls down and bounces until it stops bouncing (bouncing reduces over time)

This issue I’m facing is after the first bounce, the ball doesn’t realistically bounce high enough.

I’m not using any physics on purpose.  I’d like to achieve the bounce effect using “enterFrame” for the purpose of my game.

Any help would be greatly appreciated.

local W = display.contentWidth local H = display.contentHeight local gravity = 0.55 local myCircle = display.newCircle(W\*0.5,H-25,20) myCircle.groundLevel = H - 60 local function bounceTheBall(e)     myCircle.jumpSpeed = myCircle.jumpSpeed - gravity     print(myCircle.jumpSpeed)     myCircle.y = myCircle.y - myCircle.jumpSpeed     if (myCircle.y \>= myCircle.groundLevel) then         numberOfBounces = numberOfBounces + 1         myCircle.jumpSpeed = 20 + (numberOfBounces \* -2) -- issue probably here         myCircle.y = myCircle.groundLevel     end end numberOfBounces = 0 myCircle.jumpSpeed = 0 myCircle.y = 300 -- this can be anything Runtime:addEventListener("enterFrame", bounceTheBall)

Hey norman,

normally a bounce just inverts the current velocity.

So you might want to try:

local bounce = 0.5 myCircle.jumpSpeed = (-1)\*bounce\*myCircle.jumpSpeed

Bounce works just like in the physics engine, it determines how much of its velocity an object stores after it hit another object.

With some math you are also able to dtermine how high the bounce value needs to be for the ball to jump x times.

Greetings

Torben :slight_smile:

Hi Torben,

Thank you very much for your reply and explanation.  I truly appreciate it.

I added what you suggested and it’s great.  The ball bounces back high enough no matter where I position the ball now. Tweaking the gravity and the bounce values gets me the desired bounce ‘style’ I’m after.  That’s great and thanks again.

If I want to increase the bounce height of the ball every 5th bounce (as an example) and have the ball resuming it’s bounce pattern from the new height, what’s the best way to do it.  If you run the code below, I have the ball bouncing higher (as if it bounced on a trampoline) after every 5th bounce.  The goal is to have the ball bounce to the same height every 5th bounce (like a continuous loop) but it isn’t happening.  If you wait 30 seconds, the ball eventually loses it’s bounce height and stops bouncing.

Do you know what I’m doing wrong?

local W = display.contentWidth local H = display.contentHeight local gravity = 1 local bounce = 0.85 local myCircle = display.newCircle(W\*0.5,H-25,20) myCircle.groundLevel = H - 60 local function bounceTheBall(e)     myCircle.jumpSpeed = myCircle.jumpSpeed - gravity     myCircle.y = myCircle.y - myCircle.jumpSpeed     if (myCircle.y \>= myCircle.groundLevel) then         numberOfBounces = numberOfBounces + 1         if (numberOfBounces % 5 == 0) then             bounce = 2 -- increase the ball like bouncing on a trampoline.         else             bounce = 0.85 -- reset bounce value to what it was before.         end         myCircle.jumpSpeed = (-1) \* bounce \* myCircle.jumpSpeed         myCircle.y = myCircle.groundLevel     end end numberOfBounces = 0 myCircle.jumpSpeed = 0 myCircle.y = 600 Runtime:addEventListener("enterFrame", bounceTheBall)

Well, this one was a little bit harder to solve, but I think I came up with a solution. The main issue seems to be, that the estimations aren’t exact, so over time the ball looses more an more of its velocity. To prevent this I looked for a general formular for this kind of physics and here is what I came up with.

First let’s define some general values, that are used in the following function (this is just an explanation, not the code to use):

startY --the balls current y position in pixels endY --the y position the ball should be in pixels startV --the balls current velocity in pixels/frame endV --the velocity the should have in pixels/frame frames --the number of frames passed gravity --the gravity in pixels/frames^2

With these values defined, we can set up the following functions:

--returns the balls velocity (endV) after a sepcific amount of frames local function getEndV(startV, frames, gravity) return startV + frames\*gravity end --returns the velocity (startV) needed to reach a specific velocity (endV) after a specific amount of frames local function getStartV(endV, frames, gravity) return endV - frames\*gravity end --returns the y position of the ball after a specific amount of frames local function getEndY(startY, startV, frames, gravity) return startY + frames\*startV + (frames + 1)\*frames\*0.5\*gravity end --returns the start velocity (startV) needed to reach a certain y position (endY) in a specifc amount of frames local function getStartV(startY, endY, frames, gravity) return (endY - startY)/frames - (frames + 1)\*0.5\*gravity end

We now have the following scenario: The ball hits the floow the fith time and we want it to jump to a specific y position. At that position the ball should stopp jumping up and start falling down. In order for that to work, the ball needs to have a velocity of zero (0) at that point. But we don’t know how many frames that will take. So we combine the function above and assume that endV should be zero. For that I came up with the following function:

--gets the balls necessary starting veocity to jump to a certain position where it has an end velocity of 0 local function getJumpVelocity(startY, endY, gravity) return -gravity/math.abs(gravity)\*math.sqrt( 0.25\*gravity^2 + 2\*gravity\*(endY - startY) ) + 0.5\*gravity end

This function mighty seem odd, but it works :wink:

The only requirement is, that the gravity and the difference between startY and endY (endY - startY) need to have different signs. If the gravity is positive, the difference need to be negative and vice versa. Which makes sense, because the balls velocity cannot be 0 at endY, when endY lies in the direction of the gravity (the speed would go up and up).

I hope this makes any sense to you and helps you to understand some of the math underlying your problem :slight_smile:

Greetings

Torben

Thank you Torben.  I’ll try your suggestion and let you know how it goes.  Once again, I truly appreciate the thought and effort you have put into my current problem.

Was kinda fun to wrap my head around these basic physics stuff :smiley:

Let me know how it worked out :slight_smile:

Hey Torben,

Sorry for the delay in letting you know how I got on.  Over the past day and a half, I’ve been trying to incorporate my existing code to the code you provided above however I’m confused of what needs changing on my end.  I’ve been reading your comments and code over and over again trying to understand what it is you are explaining however I’m now at a loss of how I use the code you provided.

So if you have the time I’d very much appreciate it if you could possibly provide a main.lua with your code.

Again, thank you for assistance so far.

Hey norman,

normally a bounce just inverts the current velocity.

So you might want to try:

local bounce = 0.5 myCircle.jumpSpeed = (-1)\*bounce\*myCircle.jumpSpeed

Bounce works just like in the physics engine, it determines how much of its velocity an object stores after it hit another object.

With some math you are also able to dtermine how high the bounce value needs to be for the ball to jump x times.

Greetings

Torben :slight_smile:

Hi Torben,

Thank you very much for your reply and explanation.  I truly appreciate it.

I added what you suggested and it’s great.  The ball bounces back high enough no matter where I position the ball now. Tweaking the gravity and the bounce values gets me the desired bounce ‘style’ I’m after.  That’s great and thanks again.

If I want to increase the bounce height of the ball every 5th bounce (as an example) and have the ball resuming it’s bounce pattern from the new height, what’s the best way to do it.  If you run the code below, I have the ball bouncing higher (as if it bounced on a trampoline) after every 5th bounce.  The goal is to have the ball bounce to the same height every 5th bounce (like a continuous loop) but it isn’t happening.  If you wait 30 seconds, the ball eventually loses it’s bounce height and stops bouncing.

Do you know what I’m doing wrong?

local W = display.contentWidth local H = display.contentHeight local gravity = 1 local bounce = 0.85 local myCircle = display.newCircle(W\*0.5,H-25,20) myCircle.groundLevel = H - 60 local function bounceTheBall(e)     myCircle.jumpSpeed = myCircle.jumpSpeed - gravity     myCircle.y = myCircle.y - myCircle.jumpSpeed     if (myCircle.y \>= myCircle.groundLevel) then         numberOfBounces = numberOfBounces + 1         if (numberOfBounces % 5 == 0) then             bounce = 2 -- increase the ball like bouncing on a trampoline.         else             bounce = 0.85 -- reset bounce value to what it was before.         end         myCircle.jumpSpeed = (-1) \* bounce \* myCircle.jumpSpeed         myCircle.y = myCircle.groundLevel     end end numberOfBounces = 0 myCircle.jumpSpeed = 0 myCircle.y = 600 Runtime:addEventListener("enterFrame", bounceTheBall)

Well, this one was a little bit harder to solve, but I think I came up with a solution. The main issue seems to be, that the estimations aren’t exact, so over time the ball looses more an more of its velocity. To prevent this I looked for a general formular for this kind of physics and here is what I came up with.

First let’s define some general values, that are used in the following function (this is just an explanation, not the code to use):

startY --the balls current y position in pixels endY --the y position the ball should be in pixels startV --the balls current velocity in pixels/frame endV --the velocity the should have in pixels/frame frames --the number of frames passed gravity --the gravity in pixels/frames^2

With these values defined, we can set up the following functions:

--returns the balls velocity (endV) after a sepcific amount of frames local function getEndV(startV, frames, gravity) return startV + frames\*gravity end --returns the velocity (startV) needed to reach a specific velocity (endV) after a specific amount of frames local function getStartV(endV, frames, gravity) return endV - frames\*gravity end --returns the y position of the ball after a specific amount of frames local function getEndY(startY, startV, frames, gravity) return startY + frames\*startV + (frames + 1)\*frames\*0.5\*gravity end --returns the start velocity (startV) needed to reach a certain y position (endY) in a specifc amount of frames local function getStartV(startY, endY, frames, gravity) return (endY - startY)/frames - (frames + 1)\*0.5\*gravity end

We now have the following scenario: The ball hits the floow the fith time and we want it to jump to a specific y position. At that position the ball should stopp jumping up and start falling down. In order for that to work, the ball needs to have a velocity of zero (0) at that point. But we don’t know how many frames that will take. So we combine the function above and assume that endV should be zero. For that I came up with the following function:

--gets the balls necessary starting veocity to jump to a certain position where it has an end velocity of 0 local function getJumpVelocity(startY, endY, gravity) return -gravity/math.abs(gravity)\*math.sqrt( 0.25\*gravity^2 + 2\*gravity\*(endY - startY) ) + 0.5\*gravity end

This function mighty seem odd, but it works :wink:

The only requirement is, that the gravity and the difference between startY and endY (endY - startY) need to have different signs. If the gravity is positive, the difference need to be negative and vice versa. Which makes sense, because the balls velocity cannot be 0 at endY, when endY lies in the direction of the gravity (the speed would go up and up).

I hope this makes any sense to you and helps you to understand some of the math underlying your problem :slight_smile:

Greetings

Torben

Thank you Torben.  I’ll try your suggestion and let you know how it goes.  Once again, I truly appreciate the thought and effort you have put into my current problem.

Was kinda fun to wrap my head around these basic physics stuff :smiley:

Let me know how it worked out :slight_smile:

Hey Torben,

Sorry for the delay in letting you know how I got on.  Over the past day and a half, I’ve been trying to incorporate my existing code to the code you provided above however I’m confused of what needs changing on my end.  I’ve been reading your comments and code over and over again trying to understand what it is you are explaining however I’m now at a loss of how I use the code you provided.

So if you have the time I’d very much appreciate it if you could possibly provide a main.lua with your code.

Again, thank you for assistance so far.