Rebound length

Hi guys. In my game I have a physical ball that bounces back to infinity (I set bounce = 1). But now I would like to decide how many pixels to rebound there is a way to do it?

Jake, 

We just talked about this here: https://forums.coronalabs.com/topic/74097-physics-restitution-question/

Short answer: No, not really.

Well… you can calculate an approximate value for ‘bounce’ that will (reasonably) accurately bounce back a specific distance assuming all of these factors

  • One bounce, after that the rebound distance will be  different
  • Known starting position of both objects involved in bounce.
  • The angle-of-incidence is 0-degrees.  i.e. the rebound vector is the opposite of the motion vector proceeding it.
    • see image below for concept of angle-of-incidence
  • Circular body bouncing off square body.
    • At least two faces that collide must not interfere with rebound and must be equivalent of parallel to each-other
  • Only one body in the collision is moving.
  • Known- and fixed- acceleration or better yet known velocity at time of impact.

You can in fact handle variations in ‘angle-of-incidence’ and the ‘one-body moving’ rules, but that is even more math.

At the end of the day this is simply too much work except in the simplest of cases and even then the result is only semi-accurate.

AngleOfIncidence_800.gif

Jake, 

If you’ve taken Calculus and Physics with Calculus (I know some colleges have Physics courses w/o Calculus), you have all you need to solve this.

Box2D is trying to simulate physics exactly as you learn it in school. i.e. All the same simplifications are applied, homogenous density, point bodies, etc, etc.

( Update: Removed acceleration note because obviously we need at least one force here to slow the rebound and in all except the simplest cases this means using calculus.)

If you can’t tell, I enjoy questions like this… last post till others post or you post back Jake.

Can you tell us a little bit about how you want to use this?  i.e. Give us some scenarios around this mechanic.

We might be able to give other ideas to you to get the result you need.

Hello.

Thank you @roaminggamer

I apologize for opening a new forum but I had not seen a similar question

With physics I’m not very good so any extra help is always welcome!

In reality the dynamics I need are similar to the other post. A ball that jumps from one block to another.

I also considered not using the physics library but I think it would be more complicated…

I saw that you too at some point advised to abandon physics for this case. Have you already done something like this without physics? it’s complicated?

Kk sorry I thought it was clear, but an example is always the best thing:

io.output():setvbuf("no") display.setStatusBar(display.HiddenStatusBar) --\> Physicslocal physics = require("physics") physics.start() --physics.setGravity( 0, 9.81) physics.setDrawMode( "hybrid" ) local background = display.newRect( 160, 250, 500, 500 ) background:setFillColor( 0.7, 0.5, 0.5 ) local ball = display.newCircle(160,200, 10) ball:setFillColor( 1, 0, 0 ) physics.addBody(ball, "dynamic", { density=1, friction=0.0, bounce=1, radius=10 }) local block1 = display.newRect( 80, 240, 20, 20 ) block1:setFillColor( 0, 1, 0 ) physics.addBody( block1, "static" ) local block2 = display.newRect( 160, 280, 20, 20 ) block2:setFillColor( 0, 1, 0 ) physics.addBody( block2, "static" ) local block3 = display.newRect( 240, 320, 20, 20 ) block3:setFillColor( 0, 1, 0 ) physics.addBody( block3, "static" ) function background:touch(event) if(event.phase=="moved")then ball.x = event.x end end background:addEventListener( "touch" )

I would like to move the ball from one block to the other keeping the rebound constant.

the problems are 2:

  1. the ball does not bounce constantly

  2. I do not think that changing the position by changing x of ball is the best choice…but I have not found any other with joints

The box2d physics engine that Corona uses is fantastic and allows for some fantastic usage. In fact, I’m working on a physics based game at the moment as well. Still, as Ed already pointed out, the physics simulations aren’t perfect and there are certain limitations that you need to take into consideration.

First off , you are encountering one such problem in your sample code when you are changing the ball’s x-coordinate through the background:touch function. When an object has a physics body and is subjected to linear forces, then you cannot intervene with that object’s movement without “bugging it out”. As you are setting the ball’s x position, the physics engine is trying to adjust it at the same time, which results in weird jittering or jumping motion.

If you want to move a physics object, it’s best done by using the physics engine itself by using the linear impulse and velocity functions. For constant velocity for sideways movement, you could start by getting the object’s linear Y velocity. Then you apply that constant linear X velocity to the desired movement direction and you use the linear Y velocity that you previously retrieved. By getting that linear Y velocity and applying it, you’ll maintain the object’s Y velocity.

Depending on your preferences, you could just set the linear X velocity to 0 again once you end movement, so the object stops its X movement as soon as you let go. Alternatively, you could let the X velocity wind down so that the X movement doesn’t end so abruptly.

Secondly , regarding your question of constant jump height. You could achieve this by tracking collisions between the circle and those rects. Whenever the circle collides with a rect, then you set that constant jump height as the circle’s linear Y velocity. This would essentially reset the jump after every collision regardless of how long the circle’s previous jump was.

However, this will require some extra tricks to prevent unwanted behaviour. You might want to write rules that the linear Y velocity is reset ONLY in the case of the circle falling down and/or if it hits a rect’s top side. Otherwise it would jump higher if it hits a rect’s right, left or bottom sides too.

I had a few minutes to kill, so I just decided to roughly code what I meant into the code that you posted.

io.output():setvbuf("no") display.setStatusBar(display.HiddenStatusBar) --\> Physicslocal physics = require("physics") physics.start() --physics.setGravity( 0, 9.81) physics.setDrawMode( "hybrid" ) local reboundValue = -190 local ball local block = {} local function onLocalCollision( self, event ) if ( event.phase == "ended" ) then print( self.category .. ": collision ended with " .. event.other.category ) local vx, vy = ball:getLinearVelocity() ball:setLinearVelocity( vx, reboundValue ) end end local background = display.newRect( 160, 250, 500, 500 ) background:setFillColor( 0.7, 0.5, 0.5 ) ball = display.newCircle(160,200, 10) ball:setFillColor( 1, 0, 0 ) physics.addBody(ball, "dynamic", { density=1, friction=0.0, bounce=1, radius=10 }) ball.collision = onLocalCollision ball:addEventListener( "collision" ) ball.category = "ball" for i = 0, 2 do block[#block+1] = display.newRect( 80+i\*80, 240+i\*40, 20, 20 ) block[#block]:setFillColor( 0, 1, 0 ) physics.addBody( block[#block], "static" ) block[#block].collision = onLocalCollision block[#block]:addEventListener( "collision" ) block[#block].category = "block" end function background:touch(event) if(event.phase=="moved")then ball.x = event.x -- use physics to accomplish this. elseif(event.phase=="ended")then local vx, vy = ball:getLinearVelocity() ball:setLinearVelocity( 0, vy ) end end background:addEventListener( "touch" )

I didn’t touch the x movement, or implement the safety checks for resetting the bounce, but this should give you a good idea of what I was talking about above.

As already stated, I’d recommend using physics to move the ball on the x-axis. You could, for instance, see where the player touches the background. If the player touches to the left of the ball, then you apply linear velocity to the left and vice versa.

@XeduR @Spyric

but what happen with vx value?

if I use 

  local vx, vy = ball:getLinearVelocity() ball:setLinearVelocity( vx, reboundValue )

I get the desired bounce, but the ball keeps bouncing at vx = 0 and it’s supposed to flow with a natural collision movement.

:wacko: 

In the example above, I added the “ball:setLinearVelocity( 0, vy )” bit to try to reduce the bugged movement that originates from manually setting the ball’s x value.

Add the following print statement into your code:
 

local vx, vy = ball:getLinearVelocity() print(vx) ball:setLinearVelocity( vx, reboundValue )

If the ball doesn’t have any movement on the x axis, then it will remain as zero when using that. As long as the ball is moving left or right before the collision occurs, then getLinearVelocity gives you a linear X velocity that is not zero. This means that if you set linear X velocity to be vx, then it will retain its previous linear X velocity.
 

My main issue is if I implement this method is when the ball hit a square corner.  Its suppose to bounce with more force to a natural angle direction and in this case It’s bounce up and down. I’m using buttons not a background listener.

Can you provide us with a brief code sample of that happening?

I made another test bench for exploring the ‘solving for restitution’ issue. 
 
I am not satisfied with the result, but here it is anyways:
 
https://github.com/roaminggamer/RG_FreeStuff/raw/master/AskEd/2018/10/restitution2.zip
 
I agree, that hacking may be better. 
 
Note :  Just because it is a hack does not mean it is bad.  Sometimes the simplest and/or most direct solution is the best.

Wrong thread… post moved.

It’s all a matter of time. Prepare a mini-project to show what I explain could take 2 hours to adapt the whole scenario. It is a practice project with 10 levels, which at some point I might consider uploading it to the store for free download. I do not have the experience and speed of you.

I understand that it can be time consuming to write a sample. The reason as to why I asked was because the problem that you described, as I understand it, does not exist in the code sample that I provided.

Edit: To demonstrate my point, if you insert the following line of code into the sample above, then the ball will hit a corner and it will jump off accordingly. It will not have a linear X velocity of zero.

 

ball.x = ball.x+12

Place that anywhere after the ball has been created.

@XeduR @Spyric

Thank you very much for your advice and very useful code.

I think I can manage to get by now but I’m not sure. I’ll try and let you know.

@roaminggamer

thanks also for your sample code, it is very useful

One question, how do I know how many pixels equals “reboundValue = -190” is there a formula for this?