I'm building a Pong game and I am stuck at how the ball should bounce when hitting a horizontal wall. I tried a few methods but none seems to work.

So far I have an update method, which is called every 15ms and which does this:

float scale_x = Math.Cos(ball._angle).ToFloat(); 
float scale_y = Math.Sin(ball._angle).ToFloat(); 

//speed multiplied by scale_x is our x velocity
float velocity_x = (gameSpeed * scale_x); 

//speed multiplied by scale_y is our y velocity
float velocity_y = (gameSpeed * scale_y); 

ball._vector.x += velocity_x;
ball._vector.y += velocity_y;

and if the ball hits the horizontal wall

if (ball._vector.y + velocity_y < 0){
    Vector n = new Vector(ball._vector.x, ball._vector.y);

    float dot = (ball._vector.dot(n));
    ball._vector = ball._vector.add(n.mul((-2 * dot)));

I've been using this formula R = 2 * (V dot N) * N - V to calculate the new direction. But I can't seem to get it to work. To be honest, I'm not sure what kind of formula I need. I just need to find the new angle when it hits the wall.

Here is the solution for my game. first i made velocity_x and y instance variables.

private float velocity_x;
private float velocity_y;

then i sat the start for my direction in my constructor

float scale_x = Math.Cos(ball._angle).ToFloat(); //The x scale is the cosine of the angle
float scale_y = Math.Sin(ball._angle).ToFloat(); //The y scale is the sin of the angle

velocity_x = (gameSpeed * scale_x); //speed multiplied by scale_x is our x velocity
velocity_y = (gameSpeed * scale_y); //speed multiplied by scale_y is our y velocity

Finally in my updateBall method i leave:

ball._vector.x += velocity_x;
ball._vector.y += velocity_y;
  • \$\begingroup\$ N in the formula refers to the normal of your reflective surface, eg. your wall. A wall to the left would have a normal pointing to the right: x: 1, y: 0 etc. \$\endgroup\$ – bummzack Mar 20 '13 at 14:09
  • \$\begingroup\$ I know this might be a duplicate, have already checked that post. But I cant get it to work. So N at a horizontal wall, will have x: 0, y:1? \$\endgroup\$ – Alex Mar 20 '13 at 14:22
  • \$\begingroup\$ @Alex Yes. A horizontal wall at the bottom has { x: 0, y: 1 }, a wall at the top has { x: 0, y: -1 } (assuming your coordinates start bottom-left and increase up and right). \$\endgroup\$ – bummzack Mar 20 '13 at 14:33
  • 3
    \$\begingroup\$ @Alex Unfortunately, not being able to implement an existing answer isn't really reason enough to open a new question. If you can get 20 rep answering questions you can come to chat and ask about it. Learn some more about normals in the mean time and see if that helps. \$\endgroup\$ – MichaelHouse Mar 20 '13 at 14:33
  • \$\begingroup\$ Why not open Xna's built in method Vector2.Reflect() in your favorite assembly viewer like reflector or dotPeek and see how Xna does it? \$\endgroup\$ – Steve H Mar 20 '13 at 14:48

If what you're looking for is a simple reflection to a horizontal surface, then all you have to do is flip the y-component of the velocity vector depending on the normal of the surface you're hitting.

    velocity_y = -velocity_y;


    velocity_x = -velocity_x;
  • \$\begingroup\$ I tried to do this already, but I just end up getting a weird result, where the ball will follow the horizontal wall. \$\endgroup\$ – Alex Mar 21 '13 at 11:30
  • \$\begingroup\$ this was actually the answer, but I have tried that formula a couple of time. The problem was my update ball, that would refresh my answer no matter what I've done. So i move my scale_y & y and velocity_x & y to constructor and made velocity x & y instance variables \$\endgroup\$ – Alex Mar 21 '13 at 12:16

The formula R = 2 * (V dot N) * N - V requires normalized vectors for N, in order to calculate the new direction.

V would be a 2-dimensional vector defining the velocity or direction the ball is travelling in (in your case scale_x/y or velocity_x/y)

N defines the normal vector (length=1) of the collision plane. E.g. (0,1) for a horizontal plane and (1,0) for a vertical plane.

This will yield R, the reflected velocity vector, or the new direction

Using this formula would be overkill however, since you are only colliding with horizontal (and I expect vertical) planes. So I would suggest flipping the respective component of your velocity vector. For a horizontal plane this would be the y-component, for a vertical plane the x-component.

Another thought: Is there a specific reason why you are working with an angle for the direction of the ball? Cos and Sin is usually not good for performance and should be avoided (although in the case of pong it is probably negligible). I would try to use a direction vector instead.

  • \$\begingroup\$ There is no specific reason why im using sin and cos. I could try using a direction vector instead. \$\endgroup\$ – Alex Mar 21 '13 at 11:31
  • \$\begingroup\$ What is this formula? Is there a name? A related wiki article or something? I would like to read up on what, why and how we're achieving here. \$\endgroup\$ – Raith Oct 18 '20 at 20:34

If you simply need a new angle when a barrier is hit then:

[new angle] = 2*[barrier angle] - [old angle]

In order to cap it to the normal range you should implement that as:

[new angle] = ( 2*PI + 2*[barrier angle] - [old angle] ) mod 2*PI

Assuming radians, if you use degrees then you should use 360 instead of 2*PI.


Not the answer you're looking for? Browse other questions tagged or ask your own question.