Archived

This topic is now archived and is closed to further replies.

Pong pyshics

This topic is 5308 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I''m creating a very simple pong clone using the Windows API. I would like to know how to make the ball bounce better. Right now it only bounces at 45 degree angles. I have tried using the math functions sin and cos, but I don''t have enough knowledge on how to use them for this problem.
typedef struct{
   int x;
   int y;
   int width;
   int height;
   int dx;
   int dy;
   int radius;
   float angle;
}BALLINFO;

void CheckCollision(void)
{
   int i;
   for(i = 0; i < 2; i++)
   {
      if(player[i].y < 18 || player[i].y+player[i].height > maxy-1)
         player[i].y = player[i].oldy;
   }
   if(ball.x > player[0].x && ball.x < player[0].x+player[0].width &&
         ball.y > player[0].y && ball.y < player[0].y+player[0].height)
         ball.dx = 2;

   if(ball.x+ball.width > player[1].x && ball.x < player[1].x+player[1].width &&
         ball.y > player[1].y && ball.y < player[1].y+player[1].height)
         ball.dx = -2;
   if(ball.x <= 0)
        { player[1].score++;
          ResetValues();
        }
   if(ball.x+ball.width >= maxx)
      {
         player[0].score++;
         ResetValues();
      }
   if (ball.x < ball.radius || ball.x > maxx - ball.radius)
       ball.x *= -1;
   if (ball.y < ball.radius || ball.y > maxy - ball.radius)
       ball.y *= -1;

}

void MoveBall(void)
{
   int i;

   ball.x += ball.dx;
   ball.y += ball.dy;

   if(ball.x < 0)
   {
      ball.x = 0;
      ball.dx = 2;

   }
   else if(ball.x+ball.width > maxx)
   {
      ball.x = 320-ball.width;
      ball.dx = -2;
   }

   if(ball.y < 16)
   {
      ball.y = 16;
      ball.dy = 2;
   }
   else if(ball.y+ball.height > maxy)
   {
      ball.y = maxy-ball.height;
      ball.dy = -2;
   }
}

Share this post


Link to post
Share on other sites
When something hits a wall it bounces off at the same angle as it hit.... only in the opposite direction... so if you know that there is 360 dergees in a full turn.. you should be able to figure out what the new angle is compared to the original.. like 45 will result in 135...

Share this post


Link to post
Share on other sites
One thing you could do is change your x-deflection based on how far from the center of the paddle the ball hits.

When you have ball.dx = 2 and ball.dx = -2, what you really have is ball.dx = -ball.dx or ball.dx = -1 * ball.dx, where 1 is the deflection. If you replace the ''1'' with a variable and set it based on 1 being the center of the paddle and adding an amount representing the percentage of distance from the center of the paddle to the end of the paddle, you can get varying deflections.

Multiply the current ball.dx * -deflection and you get a new ball.dx that is no longer a predictable 45 degrees.

Share this post


Link to post
Share on other sites
Basic Trig:
Draw a cross. that is your coordinate system. 0 degrees starts at the right most point of the cross

and increases counter clockwise.

There are 4 quadrants that the cross makes and if you start in the top right and label it 1, then you

should move counterclockwise and label the quadrants 2, 3, 4, respectively. Top right should be 1,

bottom left should be 3.

Now... sin/cos/tan are all +ve in quad 1 (0-90deg). Sin is +ve in quad 2 (90-180). Tan is +ve in quad

3 (180-270deg). Cos is +ve in quad 4 (270-360).

Tan = sin / cos so from the previous paragraph it makes sense that tan is +ve in quad 1 / 3 since in

quad 1 sin and cos are both +ve and in quad 3 sin and cos are both negative. Simple right?

Finally, draw a right triangle and label each vertice A,B, and C respectively such that the line between

A and c is the longest side. B should be at the corner where the right angle is made. Now, inside the

triangle at each vertice label the angle a, b, c respectively to match A, B, C. The angle between AC/AB

should be A, CA/CB should be c and the right angle should be b.

sin(a) = opposite / hypotenuse = CB / AC
cos(a) = adjacent / hypotenuse = AB / AC
tan(a) = sin(a)/cos(a) = opposite / adjacent = CB / AB

Now if all that makes sense the math of pong should be fairly straight forward.

Angle of reflection stays the same and I'm guessing that the velocity is equal and opposite. I will

assume the paddles are on the left and right side. Left paddle will be called Pad1, right paddle Pad2.

Ok, those are my assumptions.

When a ball strikes a paddle draw a line perpendicular to the paddle at the point of impact. This line

will be used to calculate the angle of incidence and angle of reflection. Angle of incidence is the

angle that the ball is arriving at the paddle. Incidently, angle of incidence and reflection are equal.

So now that all the terms are defined we can work with the velocities of the ball. The velocity of the

ball has horizontal and vertical components which can be calculated as:

vy = mag(v) * sin(theta)
vx = mag(v) * cos(theta) where mag(v) is the magnitude of the velocity and equals sqrt(vy^2+vx^2) and

theta is the angle that of incidence / reflection at a point of impact.

For impacts on pad1/2 the vy component will always be
vy = mag(v) * sin(theta)

and vx will change direction which means
vxR = -vxI = -mag(v) * cos(theta). (R = reflection, I = incidence)

For impacts on the roof / floor:
vyR = -vyI = -mag(v) * cos(theta)
vxR = vxI = mag(v) * sin(theta)

Notice that the sin and cos function switch for paddle collisions vs. floor / roof collision. (Draw the

triangles and you should see why).

So.. I've never programmed Pong (nor any game yet), but that is the basic math that I would foresee you

needing to make it work properly. Collision detection is up to you.

**edit: copy paste from notepad added all those extra line breaks

[edited by - Sanadan on June 4, 2003 4:53:16 PM]

Share this post


Link to post
Share on other sites
Thanks for all your help. After reading about my options I''m going to use Dave Hunt''s method. However, I have a problem with this, too.

After changing my code, the ball only bounces downwards. How would I make it so the ball also bounces upwards when it''s suppose to?


if(ball.x > player[0].x && ball.x < player[0].x+player[0].width &&
ball.y > player[0].y && ball.y < player[0].y+player[0].height)
{
ball.x-=ball.dx;
ball.dx = -ball.dx;
ball.dy+=(ball.y-player[0].y+player[0].height/2)*0.1;
}

if(ball.x+ball.width > player[1].x && ball.x < player[1].x+player[1].width &&
ball.y > player[1].y && ball.y < player[1].y+player[1].height)
{
ball.x-=ball.dx;
ball.dx = -ball.dx;
ball.dy+=(ball.y-player[1].y+player[1].height/2)*0.1;
}

Share this post


Link to post
Share on other sites
Just negate the dy value and adjust y like you did x. Note that my example was based on the paddle being at the bottom of the screen. If it''s on the side, you may need to play with my example a bit and apply the values to dy instead of dx.

Share this post


Link to post
Share on other sites