Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Physics restitution question...
Started by dodi_games Oct 19 2018 08:00 AM

13 replies to this topic
[TOPIC CONTROLS]
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

dodi_games

[GLOBAL: userInfoPane.html]
dodi_games
  • Contributor

  • 317 posts
  • Corona SDK


 

Continuing in my learning to see if I can structure a test game I have another question.
 
How can I make a ball bounce forever at the restitution distance I want?
 
EX:
 
Attached File  desired-bounce.jpg   10.7KB   0 downloads
 

physics added to objects

  -- rects physics
  physics.addBody( rects[i], "static", { friction=0, bounce=0 } )

  -- ball physics
  physics.addBody( ball, { density=0.8, friction=1.0, bounce=1.0, radius=40 } )
 
Here is a ball with an initial position which when falling through physics and colliding with rect 1 returns to its original position again and again, which is the desired behavior. But moving it so that it bounces with the rect 2 rises very high until it reaches the initial position which is not the desired behavior. 
 
what I want to do is that the ball bounces eternally but at a set distance, I have tried to change the values of "bounce" to the rects and the ball but it does not work because the restitution so that it bounces forever has to be 1
 
any help?
 
thanks in advance
DoDi
 
 
 

 



[TOPIC: post.html]
#2

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,286 posts
  • Corona SDK

Restitution is a measure of how much energy is recovered in the bounce.

 

1.0 means 100 % of the energy is reclaimed, this means  a dropped ball with perfect (1.0) restitution will bounce back to the height it started at.

 

Your image shows dropping from one height and then forever bouncing up to a lower height.  

 

The math of that doesn't work.

 

You're essentially asking for 50% of the height back the first time and 100% forever after.

 

Now... having said that I hope you can work out the solution from the sentence above.  Hint: There are two parts to the solution:

 

1. Initial restitution setting.

2. You need to do something just after the first collision.

 

PS - Be aware, that restitution is not perfect in Box2D/Corona.  1.0 restitution will sometimes result in 1.0+ response, i.e. A growing bounce.


  • dodi_games likes this

[TOPIC: post.html]
#3

davebollinger

[GLOBAL: userInfoPane.html]
davebollinger
  • Corona Geek

  • 1,236 posts
  • Enterprise

i think he wants a constant-height rebound, regardless of ball velocity (which isn't real-world, and so probably could be done way easier without the physics lib fighting you, but..)

 

in the bounce 2 scenario the ball has a greater velocity (from longer acceleration due to gravity) at the moment of impact, it will then (obviously?) rebound further if it's bounce value is held constant -- which in real-world materials is almost always the case, unless acted upon in some way, fe "deflating" a ball would alter its restitution, but otherwise it remains essentially constant.

 

a hack method would be to alter contact.bounce during collision event - scaling it by some "magic" ratio of velocity.  (ie, if going too fast, producing too much rebound, then reduce bounce by some corresponding amount to compensate)

 

another hack method would be to rescale/clamp velocity right after collision to whatever "magic" value produces your desired rebound height.

 

a perhaps-less-hacky approach might be damping, though it may require a LOT of fiddling/guessing/tuning to find values that work just right.  if you use damping to limit the maximum velocity due to gravity, then you'll also limit the maximum rebound against gravity, without having to dynamically alter the bounce value. (in theory)


  • roaminggamer and dodi_games like this

[TOPIC: post.html]
#4

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,286 posts
  • Corona SDK

@davebollinger,

 

I agree.  Physics is not really the way to go for this.  There are too many instabilities and rounding errors to worry about.

 

This is as close as I can get and as you can see at the end of about 35 seconds, "Perfect" is an overstatement.

 

https://github.com/roaminggamer/RG_FreeStuff/raw/master/AskEd/2018/10/restitution.zip

 

(The calculation in my code is a little bit off and assumes the target is in the center.)

 

 

**UPDATE** - I failed to change the label for the right-most example.

 

That should say 'Perfect: 0.6...'


Edited by roaminggamer, 20 October 2018 - 10:01 AM.

  • sporkfin and dodi_games like this

[TOPIC: post.html]
#5

dodi_games

[GLOBAL: userInfoPane.html]
dodi_games
  • Contributor

  • 317 posts
  • Corona SDK

You are great. What I am looking for is that the ball always bounces at the same distance, but, it is true, it would not be a real life scenario.

@davebollinger
I will try to alter the values ​​of what you recommend me to see if I achieve that effect.

@roaminggamer
Your examples are great, they make you understand, from the code, what you want to explain. Thank you!

[TOPIC: post.html]
#6

dodi_games

[GLOBAL: userInfoPane.html]
dodi_games
  • Contributor

  • 317 posts
  • Corona SDK

Wao @roamingganer "close 0.5" is the holy grail that I always imagine... But I do not understand the way is coded, I see you use your SSK... I'm lost, does it have a way to do it without SSK? I'm not asking for code just the theory.

[TOPIC: post.html]
#7

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,286 posts
  • Corona SDK

There are no SSK dependencies.  I included that for other reasons.

 

I often find myself wanting access to table.dump() and table.print_r() which are in SSK.   

 

SSK is not used in the solution, except maybe for some global variable.



[TOPIC: post.html]
#8

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,286 posts
  • Corona SDK

I'm not sure if I can clarify this any more, but I'll try.  This is a breakdown of the code:

 

Some Helper Variables and Setting Up Physics

local cx     = display.contentCenterX
local cy     = display.contentCenterY
local fullw  = display.actualContentWidth
local fullh  = display.actualContentHeight
local left   = cx - fullw/2
local right  = cx + fullw/2
local top    = cy - fullh/2
local bottom = cy + fullh/2
local physics = require "physics"
physics.start()
physics.setGravity(0,10)
physics.setDrawMode("hybrid")

Locals Specific To Example Positions and Sizes

local size      = 80  -- ALL OBJECTS ARE 80 x 80
local radius    = 38  -- Radius of ball a little less than half of 80 so the shape fits visible part better
                      -- This actually throws off a later calculation a little accuracy wise.

local y0        = cy - 200  -- Position of top marker bottom
local y1        = cy + 200  -- Position of block top
local tween     = (y1 - y0) - size -- distance between those two spaces, less the size of the ball
local targetY   = y0 + tween/2 + size/2  -- Where target (marker 2) should be placed. i.e. Marks where
                                         -- I want ball to bounce to (based on your post)

A function to create markers, block, ball, and set up bounce/restitution

local function createParts( x, text, restitution )
   restitution = restitution or 1

   local dropMarker =  display.newImageRect( "rg256.png", size, size )
   dropMarker.x = x
   dropMarker.y = y0
   dropMarker:setFillColor( 1, 0, 0, 0.25 )

   local targetMarker =  display.newImageRect( "rg256.png", size, size )
   targetMarker.x = x
   targetMarker.y = targetY
   targetMarker:setFillColor( 0, 1, 0, 0.25 )

   local block =  display.newImageRect( "corona.png", size, size )
   block.x = x
   block.y = y1
   physics.addBody( block, "kinematic", { bounce = 0 } )

   local label = display.newText( text, block.x, block.y + 100, nil, 20)

   local ball =  display.newImageRect( "rg256.png", size, size )
   ball.x = x
   ball.y = dropMarker.y
   physics.addBody( ball, "dynamic", { bounce = restitution, radius = radius } )
   
   return ball, block
end

Two Examples That: Do not do what you want. (i.e. naive approaches)

-- Wrong
local ball, block =  createParts( cx - 225, "Wrong 1" )

local ball, block =  createParts( cx - 75, "Wrong 2", 0.5 )

One Example That: You'd think would work (it doesn't).

-- Close
local restitution = 0.5
local ball, block =  createParts( cx + 75, "Close: " .. restitution, restitution )
ball.first = true
function block.collision( self, event )
   local other = event.other
   if( event.phase == "began" ) then
      if( other.first ) then
         other.first = false
      else
         event.contact.bounce = 1 
      end      
   end
   return false
end; block:addEventListener("collision")

The collision listeners does this:

 

(Nearly) Perfect Solution

-- Perfect
local restitution = 0.5 + radius/tween
local ball, block =  createParts( cx + 225, "Perfect: " .. restitution, restitution )

ball.first = true
function block.collision( self, event )
   local other = event.other
   if( event.phase == "began" ) then
      if( other.first ) then
         other.first = false
      else
         event.contact.bounce = 1 
      end      
   end
   return false
end; block:addEventListener("collision")

This is almost exactly the same as the 'close' example, but I calculated a value for bounce/restitution.  

 

All physics objects are treated like points for the purpose of calculations.  That means the true position and travel distance of the ball is based on it's center, not the bottom.  Thus, I have to adjust the restitution as follows:

 

50% restitution + radius / travel-distance

 

tween is the travel distance.

 

i.e. need to make it a little more bouncy because it isn't falling as far as I need it for it to get enough energy.

 

This calculation is simplified by the fact that the target bounce-to  position is directly in the center (of the drop position and the block). 

 

It would be a a little harder if I allowed for arbitrary bounce target positioning.


  • dodi_games likes this

[TOPIC: post.html]
#9

dodi_games

[GLOBAL: userInfoPane.html]
dodi_games
  • Contributor

  • 317 posts
  • Corona SDK

@roaminggamer
Thanks, I will study the code more thoroughly until I can understand.

[TOPIC: post.html]
#10

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 293 posts
  • Corona SDK

I'm a bit late to the party, but I would vouch for the hacky method of solving this by simply resetting the ball's linear velocity after every collision. I just wrote a rough example of the method to jake1987.jj's post "Rebound length".

So, as @davebollinger already said, after each collision, you'd simply set the linear Y velocity to the desired value. This method will, however, require setting up some safety checks so that this doesn't occur when hitting the platforms other sides, etc.

 


  • roaminggamer, dodi_games and jake1987.jj like this

[TOPIC: post.html]
#11

dodi_games

[GLOBAL: userInfoPane.html]
dodi_games
  • Contributor

  • 317 posts
  • Corona SDK

@roaminggamer

 

Now I understand your example a little better. The difference is in "scope" because your "scope" is superior to mine. Basically you did in 100 lines what I have done in 500. To adjust all my code in your way would be a work of almost 3 weeks. However, there is a difference, you use an image to which you assign a radius, I use a circle whose radius is the edge of the image that fills it.  You also use a pre-arranged distance (y1, y0) where you can get the values and assign them to the variable "restitution", but in a free scenario, where the ball can bounce wherever it wants, I do not think it will adjust that calculation. I can not get to understand how to make the "restitution" value adapt to my "scope". However, thank you very much because you have opened my mind to other horizons.

 

I will continue studying to see what I can do.



[TOPIC: post.html]
#12

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,286 posts
  • Corona SDK

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.

[TOPIC: post.html]
#13

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,286 posts
  • Corona SDK

@dodi_games - You should forget about the mechanic for a moment and describe how it is used in your game. How will it affect game play and interaction.

Knowing this, we may be able to give you a better choice.

Often times, folks encounter a problem in their game. They then come up with a solution, but don't know how to implement it. Then they ask about implementing the solution, never telling what the original problem was.


i.e. You're focused on using 'restitution' (or some other method) to limit bounce distance, but we don't know why or how this is used in your game, nor what problem it is solving.

Maybe try giving us the 'elevator' pitch description of your game and remember to tell us why this bounce limit is important.
  • dodi_games likes this

[TOPIC: post.html]
#14

dodi_games

[GLOBAL: userInfoPane.html]
dodi_games
  • Contributor

  • 317 posts
  • Corona SDK

@roaminggamer

you are right, but this time I do not have a concrete game.  I'm goin to explain what I have.

 

-I have a menu and 10 levels

-The levels consist of 4 "screen borders", a "ball" and objects to collide, which in this case are "squares".

-In particular there is no established game mechanics, I am looking for one, that's why I have 10 levels.

-Level one has a square, level two has two, and so on.

-To move to the next level I have decided that one of the squares is the goal, so when the ball touches that square its movement stops and I go to the next level

-to move the ball I have two buttons, left and right

-and I want the ball to have a constant rebound movement, so when I move it to the right or left I can bounce with the edges of the screen or squares.....boring right?

 

I want to control the distance of the bounce because if a square is more up than another when colliding with the one below, a bounce too high is triggered as shown in the photo above.

 

and.....

 

that prevents me from playing with my objects and being able to think in wich game mechanics are fun to be able to develop a game, a good idea.

 

I started a game and discovered that I am too newbie to do it in so little time of learning, so I decided to use that project to play with it a little, discover and learn more about Corona SDK, with the hope that I can think of a good idea and be able to upload my first game, free, ads probably, to Google Play.

 

In short, I look for a constant rebound effect in which I can control the distance of the rebound, which allows me to have more control of the ball and I can think of a good idea to develop a game.

 

-------------------------------------------------------------------------------------------------------

@all

thanks guys, all of you are great.




[topic_controls]
[/topic_controls]