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.
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.
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
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
As a velocity vector for the ball, this needs to be the normalized difference vector
Hope this makes sense
[EDIT: made a correction]