问题
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.

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.
回答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]
来源:https://stackoverflow.com/questions/28163635/bouncing-a-ball-within-a-circle