Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Rebound length
Started by jake1987.jj Oct 20 2018 11:26 AM

31 replies to this topic
[TOPIC CONTROLS]
Page 1 of 2 1 2
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

jake1987.jj

[GLOBAL: userInfoPane.html]
jake1987.jj
  • Contributor

  • 211 posts
  • Corona SDK

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?

[TOPIC: post.html]
#2

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,286 posts
  • Corona SDK

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



[TOPIC: post.html]
#3

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,286 posts
  • Corona SDK

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.)


Edited by roaminggamer, 20 October 2018 - 12:44 PM.


[TOPIC: post.html]
#4

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,286 posts
  • Corona SDK

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.



[TOPIC: post.html]
#5

jake1987.jj

[GLOBAL: userInfoPane.html]
jake1987.jj
  • Contributor

  • 211 posts
  • Corona SDK

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...



[TOPIC: post.html]
#6

jake1987.jj

[GLOBAL: userInfoPane.html]
jake1987.jj
  • Contributor

  • 211 posts
  • Corona SDK

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?



[TOPIC: post.html]
#7

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,286 posts
  • Corona SDK

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.


  • Michael Flad likes this

[TOPIC: post.html]
#8

jake1987.jj

[GLOBAL: userInfoPane.html]
jake1987.jj
  • Contributor

  • 211 posts
  • Corona SDK

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


[TOPIC: post.html]
#9

XeduR @Spyric

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

  • 293 posts
  • Corona SDK

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.



[TOPIC: post.html]
#10

XeduR @Spyric

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

  • 293 posts
  • Corona SDK

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.


  • roaminggamer, dodi_games and jake1987.jj like this

[TOPIC: post.html]
#11

dodi_games

[GLOBAL: userInfoPane.html]
dodi_games
  • Contributor

  • 317 posts
  • Corona SDK

@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: 



[TOPIC: post.html]
#12

XeduR @Spyric

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

  • 293 posts
  • Corona SDK

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.
 


  • roaminggamer likes this

[TOPIC: post.html]
#13

dodi_games

[GLOBAL: userInfoPane.html]
dodi_games
  • Contributor

  • 317 posts
  • Corona SDK

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.



[TOPIC: post.html]
#14

XeduR @Spyric

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

  • 293 posts
  • Corona SDK

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



[TOPIC: post.html]
#15

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.
  • jake1987.jj likes this

[TOPIC: post.html]
#16

roaminggamer

[GLOBAL: userInfoPane.html]
roaminggamer
  • Corona Geek

  • 7,286 posts
  • Corona SDK

Wrong thread.. post moved.

Edited by roaminggamer, 21 October 2018 - 09:44 AM.


[TOPIC: post.html]
#17

dodi_games

[GLOBAL: userInfoPane.html]
dodi_games
  • Contributor

  • 317 posts
  • Corona SDK

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


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.

[TOPIC: post.html]
#18

XeduR @Spyric

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

  • 293 posts
  • Corona SDK

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.

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.



[TOPIC: post.html]
#19

jake1987.jj

[GLOBAL: userInfoPane.html]
jake1987.jj
  • Contributor

  • 211 posts
  • Corona SDK

@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



[TOPIC: post.html]
#20

jake1987.jj

[GLOBAL: userInfoPane.html]
jake1987.jj
  • Contributor

  • 211 posts
  • Corona SDK

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



[TOPIC: post.html]
#21

jake1987.jj

[GLOBAL: userInfoPane.html]
jake1987.jj
  • Contributor

  • 211 posts
  • Corona SDK

Still here.

I put the bounce checks only at the top. And I added the controls to move the ball's ".x" with physics.

I'm having problems though:

1.If the ball hits the side of a block instead of standing still, it vibrates.

2.compared to before the fluidity has improved but I think we can do more.

 

Here is the new code:

	local horizontalSpeed = 400
	local reboundValue = -190
	local ball
	local block = {}


	local background = display.newRect( 160, 250, 500, 500 )
	background:setFillColor( 0.7, 0.5, 0.5 )

	local function onLocalCollision( self, event )
	    if ( event.phase == "ended" ) then
	    	--print( self.category .. ": collision ended with " .. event.other.category )
	    	if(event.other.category == "ball")then
	    		if((ball.y+ball.height*0.5) < (self.y+self.height*0.5))then
					local vx, vy = ball:getLinearVelocity()
					ball:setLinearVelocity( vx, reboundValue )
				end
			end
	    end
	end

	ball = display.newCircle(160, 200, 10)
	ball:setFillColor( 1, 0, 0 )
	ball.category = "ball"
	physics.addBody(ball, "dynamic", { density=1, friction=0.0, bounce=1, radius=10 })
	ball.collision = onLocalCollision
	ball:addEventListener( "collision" )



	for i = 0, 2 do
		block[#block+1] = display.newRect( 80+i*80, 240+i*40, 20, 20 )
		block[#block]:setFillColor( 0, 1, 0 )

		if(i==0)then
			block[#block].height = 200
		end

		physics.addBody( block[#block], "static" )
		block[#block].collision = onLocalCollision
		block[#block]:addEventListener( "collision" )
		block[#block].category = "block"
	end
	block[#block+1] = display.newRect( 160, 380, 300, 20 )
	block[#block]:setFillColor( 0, 1, 0 )
	physics.addBody( block[#block], "static" )
	block[#block].collision = onLocalCollision
	block[#block]:addEventListener( "collision" )
	block[#block].category = "block"


	local tmp = display.newRect( 160, 100, 20, 0 )
	tmp.anchorY=1
	tmp.y = block[2].y-(block[2].height*0.5)



	local nowX, nowY = ball.x, ball.y
	function background:touch(event)
		if(event.phase=="began")then
			nowX, nowY = event.x, event.y
		 elseif(event.phase=="moved")then
		 	nowX, nowY = event.x, event.y
			--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" )


	local function enterFrame( self )
		local vx, vy = ball:getLinearVelocity()
		--horizontalSpeed
		if((ball.x <= nowX+10)and(ball.x >= nowX-10))then
			ball:setLinearVelocity( 0, vy )
		 elseif(ball.x < nowX)then
			ball:setLinearVelocity( horizontalSpeed, vy )
		 elseif(ball.x > nowX)then
		 	ball:setLinearVelocity( -horizontalSpeed, vy )
		end
	end
	ball.enterFrame = enterFrame
	Runtime:addEventListener( "enterFrame", ball )


[TOPIC: post.html]
#22

XeduR @Spyric

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

  • 293 posts
  • Corona SDK

The physics engine tries to follow the standard physics formulas within certain limitations. If I'm not mistaken, the -190 linear Y velocity is roughly equal to -190 pixels on the Y axis per second. There is variance due to the engine, frame rate and the calculations, etc. But, as for how far the -190 linear Y velocity goes depends on the gravity. This is called uniform acceleration and its formula, if I remember correctly, is a = ( Vf - Vi ) / t.


Out of curiosity, are you and dodi_games working on the same project? Your needs code-wise seem similar, if not the same, and your code is now demonstrating the issue that dodi_games was talking about and which doesn't exist in my code. :D

You are currently experiencing that "vibration issue" because of your enterFrame function. You are resetting the ball's linear X velocity every frame, so even if the ball is bouncing away from some rect that it just collided with, your code removes that bounce and resets the linear X velocity to move the ball towards the block, i.e. the ball collides, gets pushed back and reset to collide again with the block, and repeat.

Here, the most important thing for you, and for everyone trying to help you, is understanding the purpose of your game and how the ball's movement should work. The easiest method for eliminating that vibration, as you call it, is by setting a rule that the user can freely move the ball until the ball collides with a block. At this point, if the ball collides with the top of a block, you can reset that movement. If the ball collides with some other side, the movement is not reset and so the player can't keep slamming the ball into a block.

All of these are just some guesses and ideas on how you might be able to implement the movement. This will be ultimately up to you. You need to finish your plans regarding the game and its movement system. I mean, even though I've written you a sample of how this movement could be done with physics, I'm only guessing as I don't know your project and so I'm not yet 100% sold on the idea if physics are absolutely needed for this or if you could do this old school, i.e. without physics.


  • jake1987.jj likes this

[TOPIC: post.html]
#23

dodi_games

[GLOBAL: userInfoPane.html]
dodi_games
  • Contributor

  • 317 posts
  • Corona SDK

Out of curiosity, are you and dodi_games working on the same project? Your needs code-wise seem similar, if not the same, and your code is now demonstrating the issue that dodi_games was talking about and which doesn't exist in my code. :D


Nop

[TOPIC: post.html]
#24

jake1987.jj

[GLOBAL: userInfoPane.html]
jake1987.jj
  • Contributor

  • 211 posts
  • Corona SDK

@XeduR @Spyric

 

No we do not work together. Although I recognize that it is very curious that we have the same problem...

However I think it's a fairly frequent situation.

 

As for me, I'm trying to imitate something like "Doodle Jump" (https://www.youtube.com/watch?v=wjofzwaC_Oo)

The difference is that my blocks are rectangles.

 

In addition I would like that if the ball takes the rectangle to the side does not bounce but remains locked there.

 

I do not want to use physics at any cost. I would rather be able to use the most fluid and effective method.

 

Can you help me in this? Now is it clearer what I'm trying to do? thank you for your time



[TOPIC: post.html]
#25

XeduR @Spyric

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

  • 293 posts
  • Corona SDK

If you are working on Doodle Jump like "jumping physics", then you should have a look at https://docs.coronalabs.com/api/type/PhysicsContact/isEnabled.html.

 

What you could do is enable contact between the ball and the blocks only if the ball is moving down. This means that the ball can jump through the blocks from below. If you want something else, then you need to write special rules for those cases.

 

If you don't want to use physics, then you'd need to write math based collision rules for the ball and the blocks. This wouldn't be a too difficult task for something like Doodle Jump, but I think that it might be more difficult than you want. Plus, if your game is relatively simple, then using the physics themselves won't be that burdensome anyway.




[topic_controls]
Page 1 of 2 1 2
 
[/topic_controls]