2

I have a Pong-360 game in which the arc shaped paddles deflect a ball that should stay within the circular boundary. If the ball does not encounter a paddle when it gets to the boundary, it continues out of bounds and the player to last hit the ball scores. The problem I am having is returning the ball in the correct direction upon impact with a paddle. If the ball contacts a certain half of the paddle it should bounce in that direction but in any case should be returned to the opposite side of the boundary without hitting the same side of the boundary again.

Screenshot of game with added notes Right now I have accomplished bouncing by dividing the boundary into 16 slices and giving the ball a random angle within a range that depends on which slice it was at on impact. Even this does not work as intended because my math is not correct but it needs to be redone any way. I can not figure out how to obtain an angle that will ensure the ball returns to the opposite half of the boundary no matter where it was hit. I have made several attempts to get the angle from variables such as direction of travel of the ball, current position within the boundary, and position of the paddle that made contact, but so far I have experienced failure. Currently, the code for changing the ball's direction is as follows:

    public void bounce(){

        boolean changeAngle = false;

        if( bluePaddle.intersects( ball.getX(), ball.getY(), ball.getDiameter(), ball.getDiameter() ) ){

            lastHit = 1;
            changeAngle = true;
        }
        else if( redPaddle.intersects( ball.getX(), ball.getY(), ball.getDiameter(), ball.getDiameter() ) ){

            lastHit = 2;
            changeAngle = true;
        }

        if ( changeAngle ){

            //  Right side of boundary
            if ( ball.getX() > center_x ) {

                //  Quadrant 4
                if ( ball.getY() > center_y ){

                    //  Slice 13
                    if ( ball.getY() - center_y > Math.sin(3 * Math.PI / 8) ){                      
                        angle = (double) ( randNum.nextInt(90) + 90 );
                    }
                    //  Code for other slices omitted
                }//end Quadrant 4
                // Code for other quadrants omitted
            }//end right side of boundary

            //  Code for Left side of boundary omitted

            ball.setDx( (int) (speed * Math.cos(Math.toRadians(angle))) );
            ball.setDy( (int) (speed * Math.sin(Math.toRadians(angle))) );
        }//end if (changeAngle)

        bouncing = false;       
    }//end bounce method

As you can see, as it is now, the angle is simply generated at random within a range that I thought would be good for each slice. To emphasize, I primarily need help with the math, implementing it with Java is secondary. The entire code (all .java and .class files) which compiles and runs can be found here: https://github.com/pideltajah/Pong360/tree/master/Pong360

The main method is in the Pong.java file.

Any help will be appreciated.

Stack Underflow
  • 2,363
  • 2
  • 26
  • 51
  • The arrow that you drew does not seem feasible. Notice that, if the paddle were in the rightmost postition, that deflection would cause it to hit its own side. What's more, it doesn't seem possible to work out in a very sensible way. If the red paddle were on top, for instance, hitting the right side of the paddle will also send the ball against red's own wall. – dwn Jan 27 '15 at 05:29
  • You could force it to hit the center line by mapping vectors to it, but you might want to work rebounds into the strategy instead – dwn Jan 27 '15 at 05:32
  • 1
    Alternatively, maybe you could divide the circle into quarters, and each player would control two paddles 180 degrees apart (or opposite sides if on a square). If that's a dumb idea, my excuse is, it's late. – dwn Jan 27 '15 at 05:36
  • @dwn The arrow is not meant to be an exact representation of the desired result but rather it is intended to illustrate the concept I am trying to convey. As for the paddle being at the top, there are actually two game modes, one of which allows both players to travel all the way around the circle, the other restricts their movements to left / right side of boundary. I am looking for help getting the ball to go toward the opposite side of the boundary relative to where it hit and (when in left / right mode) to be directed to the other player's side even if hit at the very top or bottom. – Stack Underflow Jan 27 '15 at 05:41
  • About your comment that it doesn't seem possible to work out in a sensible way, I admit that I may not be looking at the problem in the right way and am open to suggestions regarding a better definition of the problem or a different set up for the solution, so long as the desired results can be achieved. Thanks for your input. – Stack Underflow Jan 27 '15 at 05:57

1 Answers1

1

First, find where it hit on the paddle. You can do this like so in the case of the red paddle (the blue paddle will be similar, but you may need to swap ang0 and ang1):

Edges of paddle are defined by two angles on your circle, ang0 and ang1, where ang0 is the lower edge, and ang1 is the upper edge

Assume center of circle is point (0, 0) and the ball is at point pBall = (xBall, yBall)

The ball will be at a certain angle ballAng = atan2(yBall, xBall) within the range [ang0 .. ang1]

Now convert its angle position on the paddle into a parameter between [0 .. 1]. You can define this as

u = (ballAng - ang0) / (ang1 - ang0);

Now you want to map it to the centerline, like so:

Say that the bottom position of the circle centerline is point p0, and the top of the centerline is point p1

Now define the point of intersection with the centerline as

p = p0 + u * (p1 - p0)

As a velocity vector for the ball, this needs to be the normalized difference vector

velBall = normalize(p - pBall)

Hope this makes sense

[EDIT: made a correction]

dwn
  • 543
  • 4
  • 15
  • Thank you for taking the time to reply. I will attempt to implement your solution and make further updates afterwards. Thanks again. – Stack Underflow Jan 27 '15 at 06:16
  • If you want to really get weird, you could instead treat it as a direct mapping from the pong rectangle to your pong circle, but then the ball would curve as it went along. – dwn Jan 27 '15 at 06:40
  • One last notion on it: you could let the bouncing happen normally, but add a sort of magnetic force to the centerline – dwn Jan 27 '15 at 06:42