1
votes

I'm creating a Breakout game and I've previously asked a question here but no solution was proposed. I've got simple physics to invert the Y velocity of the ball on collision with the paddle. But I to implement a more advanced physics system, for example, when the ball hits the left side of the paddle and the right side, etc... but how would I calculate where to direct the ball after collision? The norm in Breakout is to direct the ball to the left upon collision to the left of the paddle, and to the right if the collision is to the right, etc...

How do I calculate where to hit the ball? I've got plenty of variables I can use, such as all the aspects of the paddle (width, height, X position), ball (radius, height, width, X and Y velocity, X position, Y position, etc...) and I've got the motion of the paddle by using a mouse listener and subtracting the new X mouse position from the old X position so I can see how fast the paddle is moving and in what direction.

Is anyone here familiar with the basic physics and able to help me calculate the trajectory, path, velocity or direction in to send the ball after collision?!

Thanks in advance.

2
Is the paddle a rectangle? - Dawood ibn Kareem
Yes, I've got the coordinates as well of it's position and like I mentioned, all it's properties. - user3422952
So if the ball hits a vertical side of a rectangle, you just reverse the X component of its velocity; if it hits a horizontal side, you reverse the Y component. Is that what you're asking? Or are you trying to deal with the case where the paddle is moving? - Dawood ibn Kareem
Also ... do you want to take into account the relative masses of the ball and the paddle? In other words, does the ball knock the paddle at all, or is the paddle heavy enough (and the ball light enough) that the paddle itself is unaffected by the collision? - Dawood ibn Kareem

2 Answers

1
votes

We work on a Breakout game for school all the time. This how we do it. Note that this is from within a Ball class so every time to see this think Ball.

The following Bounce method calculates and applies the velocity and spin change from a bounce of the Ball.
The "factors" indicate how to translate speeds in the x and y directions into the speed parallel to the surface. If we orient our view so that the Ball is moving down toward the surface, the speed parallel to the surface is positive if movement is to the right.

The equations are derived from the physical analysis presented in: Richard L. Garwin, "Kinematics of an Ultraelastic Rough Ball", American Journal of Physics, 37, 88-92, Jan. 1969. This determines behavior for a perfectly bouncy ball (elastic collision) with spin that does not slip/slide when bouncing. A real-world analog is the Superball product by Wham-O.

We make two modifications / specializations: 1) Since we operate in two dimensions, our "ball" is a disc. This makes the moment of inertia

1/2 * M * R^2

. In the conventions of Garwin's paper, this means that alpha = 1/2. Garwin does not consider collision with a moving surface. However, it is easy to adjust things by considering movement relative to the frame of the moving surface. We simply subtract the speed of the surface from the Ball's parallel movement before computing what happens in the collision, and then add the speed back afterwards.

In Garwin's notation, we end up with:

Ca = -1/3 Cb - 4/3 Vb + 4/3 Vs

Va = -2/3 Cb + 1/3 Vb + 2/3 Vs

Here Va and Vb are the speed of the Ball parallel to the surface after and before the collision, respectively. Vs is the speed of the surface. Ca and Cb are R * spin of the Ball, after and before the collision, respectively. (In Garwin's notation, C = R * omega, where omega is the spin.)

/*
@param xFactor an int, -1, 0, or 1, giving the factor by which to
multiply the horizontal speed to get its contribution to the speed
parallel to the surface
@param yFactor an int, -1, 0, or 1, giving the factor by which to
multiple the vertical speed to get its contribution to the speed
parallel to the surface
@param speed a double, giving the speed of the surface; positive
is movement to right if we consider the surface as being horizontal
with the Ball coming down onto it
*/   
  private void bounce (int xFactor, int yFactor, double speed) {
    // can get stuck, so add a random component to the speed
    speed += 0.03 * (random.nextFloat() - 0.5);
    // obtain parallel / normal speeds for horizontal and vertical
    double vParallel = xFactor * this.getHorizontalSpeed() +
                       yFactor * this.getVerticalSpeed();
    double vNormal = xFactor * this.getVerticalSpeed() -
                     yFactor * this.getHorizontalSpeed();
    double radius = this.getImage().getHeight() / 2.0D;
    // determine Garwin's Cb and Vb
    double cBefore = radius * spin;
    double vBefore = vParallel;
    // determine Garwin's Ca and Va
    double cAfter = (-1.0D/3.0D) * cBefore + (-4.0D/3.0D) * vBefore + (4.0D/3.0D) * speed;
    double vAfter = (-2.0D/3.0D) * cBefore + ( 1.0D/3.0D) * vBefore + (2.0D/3.0D) * speed;
    // apply direction reversal to normal component
    double vNAfter = -vNormal;
    // determine horizontal and vertical speeds from parallel and normal components
    double vHAfter = xFactor * vAfter  - yFactor * vNAfter;
    double vVAfter = xFactor * vNAfter + yFactor * vAfter;
    // update the Ball's state
    this.setHorizontalSpeed(vHAfter);
    this.setVerticalSpeed(vVAfter);
    this.spin = cAfter / radius;
}
1
votes

If you do not to thus advanced physics and are content with a billiard ball like behavior, then compute the surface normal (nx,ny) at the point of collision by your favorite method (normed as in nx²+ny²=1 or nx=cos(a), ny=sin(a)) and change the direction as in

dot = nx*vx+ny*vy
vx = vx - 2*dot*nx
vy = vy - 2*dot*ny

This is for an almost stationary paddle. For a moving paddle, do as proposed and first subtract the paddle velocity pvx from vx, compute the dot product and resulting changes, and add back the paddle velocity. Or do the subtraction just in the dot product without changing vx:

dot = nx*(vx-pvx)+ny*vy
vx = vx - 2*dot*nx
vy = vy - 2*dot*ny