How to calculate new x and y velocities after a collision

1 favourites
  • 4 posts
  • Howdy. In my ever increasingly random experimentation in construct 3, I have hit another problem that probly has a super simple solution, and I'm just to dumb to see it.

    For many reasons, I have a goal to try and do this without using the physics engine behavior. I'm trying to learn how to do it myself. Just cuz.

    Here is my setup. I have a ball Sprite. It has an xvelocity and yvelocity instance variable. I have made a super simple physics script. Every tick the ball is moved in the x direction the value of it's xvelocity and it is moved yvelocity in the y direction as well. This allowed me to add a gravity constant to the yvelocity every tick. Kool. I have a ball that can fall in an arc. Now, I want the ball to bounce off a platform. With me still?

    I can detect when and where I hit this platform.

    My goal is to make a script that can take three inputs (x velocity, y velocity, and the angle of the platform's surface) and output 2 values(the new x velocity and new y velocity). Or in other words, I want a function that can bounce the ball given any flat surface angle. I just want the x and y velocities to change when this function runs.

    I think this is a trig problem, but I can't figure it out. Any ideas?

    Tagged:

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Here’s some pseudo code to do the bounce. The only trig has to do with the collision normal. The normal is perpendicular to the angle of the platform. So if you know the angle of the surface it’s enough to subtract 90 to get a perpendicular angle. Then to make the math look cleaner we can convert that angle to a vector.

    Anyways here’s the math.

    Nx,ny is the normal vector and can be calculated with:

    nx= cos(plat.angle-90)

    ny=sin(plat.angle-90)

    Next we calculate the velocity along the normal’s direction. Here vn is that velocity, and vx, vy is the x and y velocity of the object. We are utilizing a vector dot product to get the velocity along the normal’s direction.

    vn=vx*nx+vy*ny

    So far so good. Next is to do the bounce by changing the velocity.

    You only need to do the bounce if the object is going toward the platform.

    Then the bounce is done by taking the velocity along the normal, converting it back to a vector by multiplying it by the normal, and finally subtracting that twice from the velocity. If you subtracted just once, then it would just stop motion in the direction of the normal.

    if(vn >0)

    vx = vx -2*vn*nx

    vy = vy -2*vn*ny

  • Ok! I'll try it out today. Thanks.

  • awesome! this works great! Now, I will note that one of the reasons I am trying to do this myself rather than using the physics Engine is because I need as low CPU usage as possible to run on mobile. So, If anyone else wants to use this method like me, here is my set up:

    | Local number nx‎ = 0

    | Local number ny‎ = 0

    | Local number vn‎ = 0

    * On function 'bounceOff'

    * Parameter 'ballID' (Number)

    * Parameter 'angleOfWall' (Number)

    -> System: Set nx to cos(angleOfWall - 90)

    -> System: Set ny to sin(angleOfWall-90)

    ----+ Ball: Pick instance with UID ballID

    -----> System: Set vn to Ball.VelX × nx + Ball.VelY × ny

    -----> DebugText: Set text to "vn: " & (round(vn × 1000))÷1000 & " nx: " & (round(nx×1000)÷1000) & " ny: " & (round(ny×1000))÷1000

    -----> Ball: Set VelX to Ball.VelX -2×vn×nx

    -----> Ball: Set VelY to Ball.Vely -2×vn×ny

    This is a function I created that I can use to bounce the ball off any angled platform. It works great. Thanks R0J0hound. Now, because I am trying to go for as low CPU usage as humanly possible, I found that you can use that function and that debug text to get the exact values for nx and ny for any slant. Every angle has its own, and they only change if the angle of the slant does. So, If you find those values, you can set up bounces like this:

    + System: Every tick

    + System: For each Ball

    -> Ball: Set VelY to Self.VelY + worldGravity

    -> System: Set newx to Ball.X + Ball.VelX

    -> System: Set newy to Ball.Y + Ball.Vely

    ----+ System: newy > 1038 + (0.464×(newx))

    ----+ System: newx < 360

    -----> System: Set nx to 0.423

    -----> System: Set ny to -0.906

    -----> System: Set vn to Ball.VelX × nx + Ball.VelY × ny

    -----> Ball: Set VelX to Ball.VelX -2×vn×nx

    -----> Ball: Set VelY to Ball.Vely -2×vn×ny

    -----> System: Set newx to Ball.X + Ball.VelX

    -----> System: Set newy to Ball.Y + Ball.Vely

    -----> Ball: Set position to (newx, newy)

    ----+ System: Else

    ----+ System: newy > 1372 - (0.464 × newx)

    ----+ System: newx > 360

    -----> System: Set nx to -0.423

    -----> System: Set ny to -0.906

    -----> System: Set vn to Ball.VelX × nx + Ball.VelY × ny

    -----> Ball: Set VelX to Ball.VelX -2×vn×nx

    -----> Ball: Set VelY to Ball.Vely -2×vn×ny

    -----> System: Set newx to Ball.X + Ball.VelX

    -----> System: Set newy to Ball.Y + Ball.Vely

    -----> Ball: Set position to (newx, newy)

    ----+ System: Else

    ----+ System: newx < 29

    -----> Ball: Set VelX to -Ball.velX

    -----> System: Set newx to Ball.X + Ball.VelX

    -----> System: Set newy to Ball.Y + Ball.Vely

    -----> Ball: Set position to (newx, newy)

    ----+ System: Else

    ----+ System: newx > 691

    -----> Ball: Set VelX to -Ball.velX

    -----> System: Set newx to Ball.X + Ball.VelX

    -----> System: Set newy to Ball.Y + Ball.Vely

    -----> Ball: Set position to (newx, newy)

    ----+ System: Else

    -----> Ball: Set position to (newx, newy)

    That way, the computer doesn't need to calculate ny and nx for slants that you know will be common. You can just find them beforehand and plug them in. That condition is the formula for a slanted platform near the bottom of the game layout. It works great.

    That is essentially the entirety of the mini physics engine I just built. Works great.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)