Change the rebound angle

I hate to say it,but I ran that example and that is exactly what I would expect to happen.  If it did something else I’d think it were broken.

Also, this seems really artificial.  Is this shape interaction really part of your game or something you made to ‘mimic’ the behavior you’re seeing.

I guess what i’m saying is this doesn’t actually feel like the problem still.  

If we saw a concrete example that was actually like your game usage this would make more sense.  Can you describe your game mechanic for us?

Nobody wants to steal it so being protective is pointless.  Also people who steal prefer to steal the finished product.  i.e. They won’t steal a mechanic.  Oh, and there are no new mechanics so…  tell us what you really want to do with the ball(s) in your game so we can finally focus on the problem.

The problem is exactly that.

The game is this: a shuttle moves and must avoid the obstacles. Obstacles must bounce on the walls. I thought of three different modes, one with a background: square, spherical and triangular. I want the obstacles to bounce back to infinity and not that it slides to infinity.

You asked me for a simple example and that’s what I did. I think the problem is this and that further code does not help.

However if you are asking for it I have no problems. I repeat I’m not reinventing the wheel so if you believe it can be useful here is:

local physics = require("physics") physics.setDrawMode( "hybrid" ) --debug hybrid normal physics.start() physics.setGravity( 0, 0 ) --"math2do" taken from the examples of @roaminggamer local math2do = {} local mRad = math.rad local mCos = math.cos local mSin = math.sin local mSqrt = math.sqrt function math2do.scale( ... ) -- ( objA, scale [, altRet] ) or ( x1, y1, scale, [, altRet] ) if( type(arg[1]) == "number" ) then local x,y = arg[1] \* arg[3], arg[2] \* arg[3] if(arg[4]) then return { x=x, y=y } else return x,y end else local x,y = arg[1].x \* arg[2], arg[1].y \* arg[2] if(arg[3]) then return x,y else return { x=x, y=y } end end end function math2do.length( ... ) -- ( objA ) or ( x1, y1 ) local len if( type(arg[1]) == "number" ) then len = mSqrt(arg[1] \* arg[1] + arg[2] \* arg[2]) else len = mSqrt(arg[1].x \* arg[1].x + arg[1].y \* arg[1].y) end return len end function math2do.normalize( ... ) -- ( objA [, altRet] ) or ( x1, y1 [, altRet] ) if( type(arg[1]) == "number" ) then local len = math2do.length( arg[1], arg[2], false ) local x,y = arg[1]/len,arg[2]/len if(arg[3]) then return { x=x, y=y } else return x,y end else local len = math2do.length( arg[1], arg[2], true ) local x,y = arg[1].x/len,arg[1].y/len if(arg[2]) then return x,y else return { x=x, y=y } end end end function math2do.angle2Vector( angle, tableRet ) local screenAngle = mRad(-(angle+90)) local x = mCos(screenAngle) local y = mSin(screenAngle) if(tableRet == true) then return { x=-x, y=y } else return -x,y end end --=========-- --border-- --=========-- local points = { 185.06664671286 ,51.577059737104, 209.73797743297 ,56.283367774274, 233.62491053694 ,64.04470282235, 256.35073482034 ,74.738663991227, 277.55705045849 ,88.196601125011, 296.90942118574 ,104.20627451572, 314.10264855516 ,122.51520205026, 328.8655851004 ,142.8346410042, 340.9654104932 ,164.84414168699, 350.21130325903 ,188.19660112501, 356.45745014574 ,212.52373708286, 359.60534568565 ,237.44189609414, 359.60534568565 ,262.55810390586, 356.45745014574 ,287.47626291714, 350.21130325903 ,311.80339887499, 340.9654104932 ,335.15585831301, 328.8655851004 ,357.1653589958, 314.10264855516 ,377.48479794974, 296.90942118574 ,395.79372548428, 277.55705045849 ,411.80339887499, 256.35073482034 ,425.26133600877, 233.62491053694 ,435.95529717765, 209.73797743297 ,443.71663222573, 185.06664671286 ,448.4229402629, 160, 450, 134.93335328714 ,448.4229402629, 110.26202256703 ,443.71663222573, 86.375089463064 ,435.95529717765, 63.649265179657 ,425.26133600877, 42.442949541505 ,411.80339887499, 23.090578814262 ,395.79372548428, 5.8973514448423 ,377.48479794974, -8.8655851004031 ,357.1653589958, -20.965410493204 ,335.15585831301, -30.211303259031 ,311.80339887499, -36.457450145738 ,287.47626291714, -39.605345685654 ,262.55810390586, -39.605345685654 ,237.44189609414, -36.457450145738 ,212.52373708285, -30.211303259031 ,188.19660112501, -20.965410493204 ,164.84414168699, -8.865585100403 ,142.8346410042, 5.8973514448422 ,122.51520205026, 23.090578814262 ,104.20627451572, 42.442949541505 ,88.196601125011, 63.649265179657 ,74.738663991227, 86.375089463064 ,64.04470282235, 110.26202256703 ,56.283367774274, 134.93335328714 ,51.577059737104, 160, 50, } local obstacle = display.newRect( 0, 0, 10, 10) physics.addBody( obstacle, "static", { chain = points, connectFirstAndLastChainVertex = true } ) --[[local Effetti = require("libs.Effetti") Effetti.setPathCircle( obstacle, { radius = 200, startA = 0, endA = 360, numPath = 50, })]]-- --=======================-- --ball(obstacle for ship)-- --=======================-- local ballSpeed = 200 local ball = display.newCircle( 250, 350, 15 ) physics.addBody( ball, "dynamic", {density=0.1, radius=15, bounce=0.7, friction=1 } ) ball.isBullet = true local enterFrame = function( self ) local vx,vy = self:getLinearVelocity() vx,vy = math2do.normalize( vx, vy ) --normalize ==\> normalizeVec vx,vy = math2do.scale( vx, vy, ballSpeed ) --scale ==\> scaleVec self:setLinearVelocity( vx, vy ) end local angleStart = 180 local vec = math2do.angle2Vector( angleStart, true ) vec = math2do.scale( vec, ballSpeed ) ball:setLinearVelocity( vec.x, vec.y ) ball.enterFrame = enterFrame Runtime:addEventListener( "enterFrame", ball )

(start the code and wait about 10 seconds)

have you tried simply setting bounce=1.0 and eliminating all of your after-the-fact-fixup?

seems weird that you’re trying so hard to preserve velocity, yet intentionally drop nearly a third of it with each collision, just to have to fix it up manually afterward.

aside:  setting friction on the ball will have no effect if you don’t also set friction on the obstacle.  HOWEVER, you probably don’t want ANY friction as it will convert some portion of linear velocity to angular velocity.

I did some tests and you’re right. Remove friction and increase rebound helps.Cases in which the ball slips are less frequent.

However, sometimes they appear (I did some tests modifying the departure at random and waiting a few seconds).

There is no way to recognize the phenomenon just before it is present and push the ball (forcibly) to the center?

it might help to post a (yet another, but specific) sample that demonstrates this “slip”, as i for one am not sure what you mean by it.

i’m not trying to just get caught up in word definitions, but if we don’t understand, we can’t help…

“slip” per mechanical engineering would commonly have to do with the incomplete transfer of energy from one body to another…

using car analogies, in gaming (like Hill Climb Racing) or real world, it’d be like when you slam on the gas - the torque of the tires will overcome the friction with the ground, causing the tires to “slip” relative to the ground, as they rotate faster than they can impel the vehicle (aka a “burn out”).  similarly, slamming on the brakes at high velocity can cause a “slip” of the tires relative to the ground (aka a “skid”), as the friction of the tires with the ground is overcome by the forward momentum of the vehicle.

are either of those two types of effect occurring?  you appear to not be using friction, so no rotation of the ball, so it isn’t clear what “slipping” would mean.

thought:  are you talking about the inelastic collisions that box2d resorts to on very glancing collisions, such that a colliding object FAILS to bounce during collision – is THAT your “slip”?

if so, there are things you can tweak A BIT (fe a fixed time step, reduction of physics scale) but can’t fully fix without changing/recompiling box2d’s source code velocity threshold.

First of all, thank you again for your time. It’s really important for me to solve this problem.

I think my case is the second one. The problem is that the ball “flows” along the circumference:

This usually happens after a series of rebounds that he portrayed with the simple drawing (simplified steps):

At this point I think the best idea is to intervene in step 3 or 4 and avoid getting to 5.

I do not have enough mathematical knowledge to do that but I think we can calculate the angle of the ball with respect to the circle every time the ball slams on it. Therefore, if the angle is too wide, force the ball to a narrower angle.

If there are other solutions I’m happy. I’m interested in any solution that always works. I hope I explained myself well this time. Not being a native speaker does not help me …

try the following as experiments:

physics.setTimeStep(1/display.fps) physics.setScale(10)

one or both of those might help, though may cause other “side effects” that you then need to deal with

in theory the following would solve your problem:

physics.setMKS("velocityThreshold", 0)

though it has never actually worked (that i’m aware of)

refs: docs or google it

I’m all testing for the whole evening.

it seems that the best results are given by:

physics.setScale(10)

the cases have been reduced considerably.

As I said before I would have preferred a more “safe” solution but for now I will go ahead with this.

I thank you very much for helping me to improve my problem! :slight_smile:

I thought I’d quickly chime in.

@jake1987.jj, the code and the associated images that you posted is how the physics would work in reality. Intervening with how the ball bounces off the walls can be problematic because it will lead to unexpected behaviour and it will make it harder for the player to understand and predict how the ball will move in its environment.

Now, if you are determined that this is what you want, then there are several methods for approaching this issue. Perhaps the easiest method would be to utilise collision detection.

Whenever the ball collides with another object, store the collision event’s x and y coordinates, as well as the object that the ball collided with and at what time the collision occurred. So once the ball has collided once, you can compare all subsequent collisions with the previous collision.

First and foremost, when a new collision occurs, check if the object that the ball collided with is the same as the previous object. If it isn’t the same object, you don’t need to do anything. If it is the same object, then you may encounter that wall sliding, so then you’d check how much time has passed since the previous collision. You can set an arbitrary time window to control for this. If too little time has passed since the previous collision, then you may want to intervene. If you do decide to intervene, you can calculate the direction that the ball is travelling based on the previous collision’s x and y coordinates, as well as the current collision’s x and y coordinates. Now you could write another arbitrary rule for which direction the ball should bounce off to relative to the direction that you just calculated, such as the 90 degree angle that you previously mentioned.

@XeduR @Spyric

Thank you for intervening. In reality your approach is much more similar to mine than that of others who are intervented.

I had thought about your approach in recent days and some tests.

It also works well enough unique flaw and that it can be used mainly when we are already in step5 (see previous drawing). I hope to intervene already in step3 seen the angle is already quite large that is formed between ball and edge.

As I am writing to you I am thinking that a good solution could be that of aumtera as long as possible between one interview and another. But without exaggerating to avoid other problems. I do some tests now!

As I said before I am aware of the fact that it is not an extremely natural behavior. But I think that if corrected in the right way, it may seem natural enough

That solution could intervene as soon as step 2. It only depends on what time window you set. If you set a too long time window, then the code might run on every collision, whereas if it is too brief, then it might run too infrequently. But, as you said, this’ll need a lot of testing.

You can alternatively use number of frames instead of milliseconds to measure time.
 

Hey Jake,

If you can zip up a little sample to share with us, that would be helpful.

Question:  How did you make the outer circle?  Did you use a physics chain body or did you a program like physics editor to describe the object?

I probably sound like a broken record because I’m always the guy that says “Sheesh, why don’t you just write your own simple physics for something like this?” but I would repeat my statement here.

It would be a lot simpler and give you loads more control, from what I see here. If there are other parts of the physics mechanics not discussed here I stand corrected, but the things asked here are peanuts using simple math and some trigonometry.

@sporkfin,

When I saw that circle body, I actually realised that I might need something similar in one of my projects. I’ll write a function later today that’ll create (rough) vertices for a circle and I’ll share it on the forums. It shouldn’t be more than a 5 to 10 minute task.

Update : I’ve written the function and it’s available at https://forums.coronalabs.com/topic/73653-creating-vertices-for-a-circle/. I’ll be setting up a GitHub account at a later date and the code, as well as much more, will then be available there as well.

@sporkfin

If the bodies are circular, I use a function similar to the one posted by @XeduR @Spyric.

if instead I have polygons I do two things:

  1. If these forms only need one size, I use programs like physicsEditor

2. if these shapes need me more dimensions I create the vertices manually where each point is based on the dimension of the polygon itself (this takes me a lot of time)

If the polygon has more than 8 vertices then I use the string instead of a multi-element body.

For the zip file I hope to be able to achieve the effect I want and in that case I will not have problems sharing

@Jake

Just double checking - you have checked in physics drawmode to make sure you don’t have any errant vertices causing the ball to behave strangely?

@sporkfin

I had not done it carefully.

After your suggestion I did some checks but nothing unusual. Good idea anyway!