1

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.

user3422952
  • 319
  • 2
  • 8
  • 17
  • Is the paddle a rectangle? – Dawood ibn Kareem Apr 16 '14 at 20:59
  • Yes, I've got the coordinates as well of it's position and like I mentioned, all it's properties. – user3422952 Apr 16 '14 at 21:03
  • 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 Apr 16 '14 at 21:05
  • http://en.wikipedia.org/wiki/Classical_mechanics – Alex Salauyou Apr 16 '14 at 21:07
  • 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 Apr 16 '14 at 21:11
  • I've already got basic physics like that @DavidWallace, but using that the ball follows the same square route. I'm trying to implement physics to let the user actually control where the ball goes. – user3422952 Apr 16 '14 at 21:25
  • So you are trying to implement friction between the ball and a moving paddle? Or are you just trying to deal with the case where the ball hits the edge of the paddle, instead of the long side? You need to be FAR more specific than just saying "do physics". – Dawood ibn Kareem Apr 16 '14 at 21:38
  • I'm trying to work out how to calculate the direction of the ball after it just generally hits the paddle apart from just inverting the `Y` velocity. – user3422952 Apr 16 '14 at 22:03
  • This question appears to be off-topic because it is about collision physics and not software development. You might actually get an answer on [physics.se] – Jim Garrison Apr 16 '14 at 22:22
  • I can't help you if you don't answer my questions. Are you interested in the frictional effect, where the ball is briefly "dragged along" by the motion of the paddle? Are you interested in what happens if the ball hits the edge of the paddle, instead of its main surface? Either of these, of course will depend on the speed that the paddle is moving at the moment of impact. Are you interested in taking into account the fact that the ball will "knock" the paddle a little? Please be more specific about what you are trying to achieve. – Dawood ibn Kareem Apr 16 '14 at 22:26
  • If I recall correctly, hitting the ball with the left or right edge of the paddle reflected the ball at a sharper angle than hitting the ball with the middle of the paddle. Basically, divide the paddle into 4 areas. – Gilbert Le Blanc Apr 17 '14 at 00:20
  • Gilbert, I've divided it into 3 sections, left, right and middle. The problem is, I need to work out what the "sharper" angle actually is. – user3422952 Apr 17 '14 at 09:07
  • You could do a ratio from -1 to 1, -1 being the farthest left, 1 being the farthest right, and you can calculate the angle by taking 0 degrees if it hits the center, and ratio all the way to about 70 degrees * (position of the ball relative to the paddle, -1 to 1). – Samich Apr 17 '14 at 17:53

2 Answers2

1

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;
}
ialexander
  • 898
  • 10
  • 28
  • FYI, every single inline comment you have should actually be a javadoc comment on a separate method. You are doing _way_ too many things in the `bounce` function, and you need to split it up into multiple functions. – AJMansfield Apr 19 '14 at 01:17
  • 3
    @Ajmansfield wow. FYI, This is a tiny method. There is no need to break it up more as it only does one thing. This is the implementation of a single algorithm. We would have no need to reuse any part of this anywhere else in the program. Thanks for your opinion though. – ialexander Apr 19 '14 at 04:07
1

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
Lutz Lehmann
  • 25,219
  • 2
  • 22
  • 51