locked
trigonometry for game? RRS feed

  • Question

  • I am trying to make a game, in which you are trying to get a ball from a starting position to the end position. How can I get the ball to bounce and roll, and bounce off of walls in the right ways? Also, I need other balls to hit this main ball, and for the ball to roll away accordingly.
    ~~AirWaves!!~~
    Monday, May 23, 2011 1:38 AM

Answers

  • The gradient is an angle, calculated from the ArcTan(y/x) where y/x is the slope (y pixels per x pixels).  The angle (gradient) is useful to plot the line of the slope - I did a triangle, but it could easily just be a line.  The vector for a line with gradient angle (A radians) is just (Cos(A),Sin(A)). I used a very long line 10*gw to ensure that the triangle filled the lower part of the screen.

    If we want the line to have X2-X1 = gw, then the Y2-Y1 is Tan(A).gw.  Therefore if the line starts at (0,100), it will end at (gw,100+gw.Tan(A)) and have the required gradient A.

     

    Above are the basic trig formula to calculate gradients and vectors from directions.  There are many texts on this, Wikipedia is a good start.

    When one ball his another they recoil in such a way that momentum is conserved.  Momentum is mass times velocity and is a vector (X and Y components in 2D) just like velocity.  Each component (X and Y) of the total momentum (we can add or sum the momentum from each ball to get the total) before and after the collision is conserved (the same before as after).  The balls change direction or bounce, but their total momentum remains constant.  This is just a law of physics - it is true because it is always seen to be true - there may be philosophical reasons why it should be true, but basically this is just how it is.

    This is true whether we calculate looking down on the balls, or traveling with one of the balls or in any constant moving reference frame (like a moving camera above the balls will also calculate that momentum is conserved).  This means that we can choose any constantly moving frame to do our calculations, by simply adding the same moving frame velocity vector to both balls, calculate the bounce and then subtract the velocity vector we used to transfer to the calculating frame. 

    This is actually a fundamental law of physics that any conservation principal (like momentum or energy or mass) should equally apply for any constant moving observer - it was a staring point for Einstein and his relativity.  Note that the calculated momentum is different for any moving reference frame, but that while remaining in that frame: momentum, energy, mass etc are constant - the universe has the same laws of physics for anyone looking at it while traveling with a constant velocity.  In fact there is no stationary frame - they are all 'relative' and equally equivalent.  Are you stationary in your car or your house, is the center of the earth, sun, galaxy, universe stationary?

    If we choose the center of mass moving frame, where the total momentum is zero before during and after the collision the maths of working out the collision is much simpler - we can treat each ball separately using the vectors in earlier post.

    This is the basics of the physics - its implementation in SmallBasic is not too hard, just manipulating velocity vectors.  Start simple with 2 balls hitting each other - if they are rolling it will be easier since the collision is head on (no glancing hits).  I coded a small extension to the last rolling ball case for multiple colliding balls which I can post or if you prefer to try yourself all the better.



    • Marked as answer by AirWaves Thursday, May 26, 2011 4:51 AM
    Wednesday, May 25, 2011 6:13 PM

All replies

  • If the walls are horizontal and vertical, then for each collision all that happens is that the velocity component perpendicular to the wall is reversed when the ball hits the wall.  To do a rolling ball you just need to rotate the ball as it moves (assuming you are using an image for the ball - a png with transparency around the ball would be best - make sure the image is exactly the same size as the ball).  The amount of rotation just depends on the velocity, again assuming the ball is rolling horizontally or vertically.

    If the ball radius is r and the velocity is v and you are using an update time of dt (possibly=1), i.e. every time-step the ball position is updated by x=x+v*dt or y = y+v*dt, then in this time the perimeter of the ball rolls v*dt.  The perimeter is 2*pi.r, and hence the fraction of a full circle (2.pi) rotated is v*dt/(2*pi.r), this is an angle of v*dt/r radians or (v*dt/r)*(180/pi) degrees.

    For balls to hit and bounce off each other you can still do it without trig (assuming fully elastic collisions and doing the calcs in center of mass reference frame).  The methods to calculate this in 2D are little more involved so I won't add it here unless you want it.  These more general methods also cover non-horizontal/vertical and also oblique (glancing) collisions.

    Post some simple prototype code if you need some suggestions for it.



    Monday, May 23, 2011 7:30 PM
  • This is a general method for collisions - since it doesn't need trig, just basic vectors it may be useful for any general SmallBasic collision physics project.  I give the derivations, but the rules can be used without fully understanding the physics.

    All collisions are based on Newton's laws of motion - in particular importance are:

    1] Conservation of momentum

    The conservation of momentum is about the momentum of all objects before a collision equaling that of all objects after the collision. 
    The equations can often be much simplified if we calculate everything in a center of mass reference frame (i.e. the velocity where the total momentum is zero, since it is zero before and after the collision).

    2] Conservation of energy

    The conservation of energy is about how much energy is lost in the collision - it affects things like the recoil angle and how much energy is passed from one object to the next (think Newton's cradle etc). 
    We can often make the assumption that the actual collision is completely elastic - no energy is lost and this leads to conclusions like the bounce angle is equal to the collision angle.
    This can simplify the maths and reduce the problem to that of vectors.

    A general example:

    mass 1 (m) hits mass 2 (M).
    mass 1 has initial velocity (ux,uy) and mass 2 has initial velocity (Ux,Uy)
    After the collision mass 1 has velocity (vx,vy) and mass 2 has velocity (Vx,Vy)

    Before the collision momentum of mass1 is (m.ux,m.uy) and mass 2 is (M.Ux,M.Uy)
    After the collision the momentum are (m.vx,m.vy) and (M.Vx,M.Vy)

    The center of mass of the objects has a velocity (Cx,Cy).  By definition of center of mass, the total momentum of the center of mass is zero.
    If we do all the calculations in this frame, the velocity of each mass in the center of mass frame is (ux-Cx,uy-Cy) and (Ux-Cx,Uy-Cy) and its momentum sum is zero.

    m(ux-Cx) + M(Ux-Cx) = 0 means Cx = (m.ux+M.Ux)/(m+M) and similarly Cy = (m.uy+M.Uy)/(m+M)

    If the normal to the bounce direction is known then we can use simple geometry to calculate the velocities after the collision in this inertial frame.

    STEP1 - Calculate the center of mass velocity (Cx,Cy) and then the relative velocities of the two balls in this frame (ax,ay) = (ux-Cx,uy-Cy) and (Ax,Ay) = (Ux-Cx,Uy-Cy)

    STEP2 - Find the direction unit vector (nx,ny) for the normal direction of bounce - for a wall this is perpendicular to the wall, for two hitting balls it is the direction between the two centers when the balls are just touching.

    STEP3 - Update the center of mass recoil velocities (bx,by) and (Bx,By)

    Using the diagram for one ball (bold text below is a vector).

    n = unit vector in direction (DO)
    u = (AO) - incoming ball velocity (in center of mass frame)
    v = (OB) - recoil velocity (in center of mass frame with fully elastic collision the length of u = length of v and the angle AOD = DOB

    The length of DO = L = n.u (dot product n.u = nx*+ux + ny*uy).
    Also by symmetry CA = -OB and CD = DO

    Therefore CO = 2Ln = CA + AO = -v + u
    Therefore v = u - 2Ln

    STEP4 - Update the original frame recoil velocities (vx,vy) = (bx+Cx,by+Cy) and (Vx,Vy) = (Bx+Cx,By+Cy)

    Example1:

    A ball traveling with velocity u=(5,10) hits a stationary vertical wall U=(0,0)
    The wall is infinitely massive compared to the ball so the center of mass velocity = (0,0) (Calculate (Cx,Cy) when M is much bigger than m)
    n = (1,0)
    L = n.u = 5*1 + 10*0 = 5
    Recoil velocity v=(5-2*5*1,10-2*5*0) = (-5,10)
    This is the simple wall bounce

    Example 2:

    A moving ball u=(6,8) hits a stationary ball U=(0,0) head on
    Center of mass velocity (balls the same mass, M=m) is C=(3,4) therefore ball velocities in this frame are:
    a = (3,4) and A = (-3,-4)
    n = unit vector in center of mass frame in the direction of impact = (3/5,4/5)

    First ball:
    L = n.a = 9/5 + 16/5 = 5
    Recoil velocity b = (3-2*5*3/5,4-2*5*4/5) = (-3,-4)
    In original frame v = (0,0)

    Second ball:
    L = n.A = -9/5-15/5 = -5
    Recoil velocity B = (-3+2*5*3/5,-4+2*5*4/5) = (3,4)
    In original frame V = (6,8)
    The balls pass all momentum from moving ball to stationary ball (just like on a snooker table with no spin)

    Here is an example program where I used these methods for a curling game, Import DXS327.



    Monday, May 23, 2011 9:50 PM
  • Thanks for your previous responses, but if you wanted to make a ball roll down an inclined plane, with increasing velocity, what would you need to do?
    ~~AirWaves!!~~
    Tuesday, May 24, 2011 4:41 AM
  • This may seem really irritating to you (I'm sorry if so), but I don't know what you mean. I am really bad at physics. Could you please try explaining like you would to a complete beginner?

    Thanks litdev, and sorry for all this trouble.


    ~~AirWaves!!~~
    Tuesday, May 24, 2011 4:46 AM
  • AirWaves,

    First, I am in no way irritated - exactly the opposite - I do this because I enjoy playing with SmallBasic and science in small programs.  I would like more people, especially children, to have fun learning about how computer software actually works and perhaps a bit of science as well.

    Movement is all about forces and energy (Newton), but boiled down:

    1] A force gives rise to an acceleration - gravity is a force that accelerates objects vertically down at 10ms-2.

    2] An acceleration changes the speed (or direction) of an object (its velocity)

    3] The velocity changes the position of an object

    4] When balls hit objects they experience forces which result in accelerations (very rapid accelerations over a short time are called impulses and effectively exchange momentum)

    So to model something like this we need the physics that describes the acceleration (or force) applied to objects and the rest just runs from there.  Note we always need vectors for acceleration, velocity and position (that is an X and Y coordinate).

    A ball rolling down a slope:

    Forget the physics of the ball interacting with the slope (its about the equal and opposite force applied by the slope to the ball), but we know that the ball will accelerate in the direction of the slope. 

    Say the slope is inclined down at 45degrees, this implies an acceleration in this direction, say Acc=(1,1) or (5,5), anything where the AccX = AccY.  If the slope is at angle A (relative to the horizontal), then the Acceleration is some multiple of (Cos(A),Sin(A)).

    For different slopes in the same vertical gravity (g) it would be AccX = g.Sin(A).Cos(A) and AccY = g.Sin(A).Sin(A).

    For a vertical slope (Cliff) Acc=(0,g) and a horizontal slope (No slope) Acc=(0,0) and a 45degree slope Acc=(g/2,g/2) since Cos(45) = Sin(45) = 1/sqrt(2)

    We assume an equal timestep dt, say 1 unit - this controls the frequency of updates or speed of playback:

    The velocity is updated as VelX = VelX + AccX*dt and VelY = VelY + Acc*dt (sometimes we might use dt/2 to calculate the mean velocity over the time-step)

    The position is updated as PosX = PosX + VelX*dt and PosY = PosY + VelY*dt

    And thats it.

    All you need is to position the ball at the top of the slope with initial velocity = (0,0) and let it go.

    To rotate the ball, just update an angle by (v*dt/r)*(180/pi) degrees, where v is ball speed = sqrt(velX*VelX + VelY*VelY) and r is its radius.

    A simple example of this - import SPZ804 - note most of the trig in this is just fussy positioning of the ball initially - unnecessary.

     








    Tuesday, May 24, 2011 10:36 AM
  • Thank you very much litdev. But in your example program, you drew the triangle using this:

    GraphicsWindow.FillTriangle(0,100,0,10*gh,10*gw*Math.Cos(gradient),100+10*gw*Math.Sin(gradient))

    What would you do to get a 45 degree angle like that? Or any angle you would like?

    EDIT: I found that changing the gradient would change the angle, but what would you do to calculate it? How could you make an angle like that just using Shapes.AddLine()?

    Also, can you explain again the physics of one ball hitting another, like explaining to a beginner?

    I am just learning this stuff, and it seems really interesting to me!


    ~~AirWaves!!~~

    Wednesday, May 25, 2011 5:52 AM
  • The gradient is an angle, calculated from the ArcTan(y/x) where y/x is the slope (y pixels per x pixels).  The angle (gradient) is useful to plot the line of the slope - I did a triangle, but it could easily just be a line.  The vector for a line with gradient angle (A radians) is just (Cos(A),Sin(A)). I used a very long line 10*gw to ensure that the triangle filled the lower part of the screen.

    If we want the line to have X2-X1 = gw, then the Y2-Y1 is Tan(A).gw.  Therefore if the line starts at (0,100), it will end at (gw,100+gw.Tan(A)) and have the required gradient A.

     

    Above are the basic trig formula to calculate gradients and vectors from directions.  There are many texts on this, Wikipedia is a good start.

    When one ball his another they recoil in such a way that momentum is conserved.  Momentum is mass times velocity and is a vector (X and Y components in 2D) just like velocity.  Each component (X and Y) of the total momentum (we can add or sum the momentum from each ball to get the total) before and after the collision is conserved (the same before as after).  The balls change direction or bounce, but their total momentum remains constant.  This is just a law of physics - it is true because it is always seen to be true - there may be philosophical reasons why it should be true, but basically this is just how it is.

    This is true whether we calculate looking down on the balls, or traveling with one of the balls or in any constant moving reference frame (like a moving camera above the balls will also calculate that momentum is conserved).  This means that we can choose any constantly moving frame to do our calculations, by simply adding the same moving frame velocity vector to both balls, calculate the bounce and then subtract the velocity vector we used to transfer to the calculating frame. 

    This is actually a fundamental law of physics that any conservation principal (like momentum or energy or mass) should equally apply for any constant moving observer - it was a staring point for Einstein and his relativity.  Note that the calculated momentum is different for any moving reference frame, but that while remaining in that frame: momentum, energy, mass etc are constant - the universe has the same laws of physics for anyone looking at it while traveling with a constant velocity.  In fact there is no stationary frame - they are all 'relative' and equally equivalent.  Are you stationary in your car or your house, is the center of the earth, sun, galaxy, universe stationary?

    If we choose the center of mass moving frame, where the total momentum is zero before during and after the collision the maths of working out the collision is much simpler - we can treat each ball separately using the vectors in earlier post.

    This is the basics of the physics - its implementation in SmallBasic is not too hard, just manipulating velocity vectors.  Start simple with 2 balls hitting each other - if they are rolling it will be easier since the collision is head on (no glancing hits).  I coded a small extension to the last rolling ball case for multiple colliding balls which I can post or if you prefer to try yourself all the better.



    • Marked as answer by AirWaves Thursday, May 26, 2011 4:51 AM
    Wednesday, May 25, 2011 6:13 PM
  • Thank you very much, litdev. Now I understand what you are saying. Yes, can you please post the extension? This should be interesting. Now I can make some cool games!
    ~~AirWaves!!~~
    Thursday, May 26, 2011 4:51 AM
  • I am making a game, and here is the publish code: JJZ993. Needs the Data Extension. I only have level 1 up. Here are the controls for level 1:

    Space: Start rolling the ball

    1: Add a rectangle

    R + move mouse: Rotates the last block placed

    Ctrl+move mouse: Moves the last block placed

     

    The point of the game is to get the ball to the goal. You need a ball picture in the directory, named "img.png." I used some of your code, litdev for the beginning, and rolling.

     

    I just need help in coding the ball rolling off the start platform, and onto the other rectangles, and if it gets to the goal. How can I do this? In future, I am planning to add balls that launch from cannons, and knock the ball out of place.


    ~~AirWaves!!~~
    Thursday, May 26, 2011 6:17 AM
  • Import XTH499
    Thursday, May 26, 2011 7:53 PM