I'm working on a Breakout game, and I'm having a brick collision problem. The ball bounces off the wall, oar and brick. However, when the ball touches the oar, the oar disappears, although I seem to have prescribed that the ball in this case should rebound. I'm really stuck on this one. How can I fix it?
public class Breakout extends WindowProgram {
/**
* Width and height of application window in pixels
*/
public static final int APPLICATION_WIDTH = 400;
public static final int APPLICATION_HEIGHT = 600;
/**
* Dimensions of game board (usually the same)
*/
private static final int WIDTH = APPLICATION_WIDTH;
private static final int HEIGHT = APPLICATION_HEIGHT;
/**
* Dimensions of the paddle
*/
private static final int PADDLE_WIDTH = 60;
private static final int PADDLE_HEIGHT = 10;
/**
* Offset of the paddle up from the bottom
*/
private static final int PADDLE_Y_OFFSET = 30;
/**
* Number of bricks per row
*/
private static final int NBRICKS_PER_ROW = 10;
/**
* Number of rows of bricks
*/
private static final int NBRICK_ROWS = 10;
/**
* Separation between bricks
*/
private static final int BRICK_SEP = 4;
/**
* Width of a brick
*/
private static final int BRICK_WIDTH =
(WIDTH - (NBRICKS_PER_ROW - 1) * BRICK_SEP) / NBRICKS_PER_ROW;
/**
* Height of a brick
*/
private static final int BRICK_HEIGHT = 8;
/**
* Radius of the ball in pixels
*/
private static final int BALL_RADIUS = 10;
private static final int DIAMETER = 2 * BALL_RADIUS;
/**
* Offset of the top brick row from the top
*/
private static final int BRICK_Y_OFFSET = 70;
/**
* Number of turns
*/
private static final int NTURNS = 3;
private static final double DX = 1;
RandomGenerator rgen = RandomGenerator.getInstance();
private void moveBall(GOval o) {
double vx;
double vy = 1;
vx = rgen.nextDouble(1.0, 3.0);
if (rgen.nextBoolean(0.5))
vx = -vx;
while (o.getY() < HEIGHT) {
if (ballAboveRoof(o) && vy < 0) {
vy = -vy;
}
if (ballBehindWallR(o) && vx > 0) {
vx = -vx;
}
if (ballBehindWallL(o) && vx < 0) {
vx = -vx;
}
if (ballBelowFloor(o)) {
GLabel l = new GLabel("GAME OVER");
l.setColor(Color.RED);
l.setFont("Verdana-30");
l.setLocation(((getWidth() - l.getWidth()) / 2), ((getHeight() + l.getAscent()) / 2));
add(l);
break;
}
if (getCollidingObject(o) == paddle) {
println("Paddle");
vy = -vy;
}
if (getCollidingObject(o) != brick) {
println("Brick");
remove(getCollidingObject(o));
}
o.move(vx, vy);
pause(10);
}
}
GRect bricks;
GRect brick;
private GRect paddle;
GOval o;
// GObject collider = getCollidingObject(o);
private GObject getCollidingObject(GObject o) {
double x = o.getX(), y = o.getY();
if (getElementAt(x, y) != null) {
return getElementAt(x, y);
} else if (getElementAt(x, y + BALL_RADIUS * 2) != null) {
return getElementAt(x, y + BALL_RADIUS * 2);
} else if (getElementAt(x + BALL_RADIUS * 2, y + BALL_RADIUS * 2) != null) {
return getElementAt(x + BALL_RADIUS * 2, y + BALL_RADIUS * 2);
} else if (getElementAt(x + BALL_RADIUS * 2, y) != null) {
return getElementAt(x + BALL_RADIUS * 2, y);
} else {
return null;
}
}
private boolean ballAboveRoof(GOval o) {
return o.getY() <= 0;
}
private boolean ballBelowFloor(GOval o) {
return o.getY() + o.getHeight() >= getHeight();
}
private boolean ballBehindWallL(GOval o) {
return o.getX() <= 0;
}
private boolean ballBehindWallR(GOval o) {
return o.getX() + o.getWidth() >= getWidth();
}
private GOval addBall() {
int x = (getWidth() - DIAMETER) / 2;
int y = (getHeight() - DIAMETER) / 2;
GOval o = new GOval(x, y, DIAMETER, DIAMETER);
o.setFilled(true);
o.setFillColor(Color.BLACK);
o.setColor(Color.BLACK);
add(o);
return o;
}
private void addPaddle() {
paddle = new GRect((WIDTH - PADDLE_WIDTH) / 2.0, HEIGHT - PADDLE_Y_OFFSET, PADDLE_WIDTH, PADDLE_HEIGHT);
paddle.setColor(Color.BLACK);
paddle.setFilled(true);
paddle.setFillColor(Color.BLACK);
add(paddle);
}
public void mouseMoved(MouseEvent mouseEvent) {
int newX = mouseEvent.getX();
if (newX - (double) PADDLE_WIDTH / 2 >= 0 && newX + (double) PADDLE_WIDTH / 2 <= getWidth()) {
paddle.setLocation(newX - (double) PADDLE_WIDTH / 2, HEIGHT - PADDLE_Y_OFFSET);
}
}
private void addBricks() {
for (int i = 0; i < NBRICK_ROWS; i++) {
for (int j = 0; j < NBRICKS_PER_ROW; j++) {
addBrick(i, j);
}
}
}
private void addBrick(int i, int j) {
int x = BRICK_SEP / 2;
int n1 = i < NBRICKS_PER_ROW ? 1 : 0;
int n2 = j < NBRICK_ROWS ? 1 : 0;
GRect brick = new GRect(x + i * (BRICK_WIDTH + (BRICK_SEP) * n1), BRICK_Y_OFFSET + j * (BRICK_HEIGHT + BRICK_SEP * n2), BRICK_WIDTH, BRICK_HEIGHT);
brick.setFillColor(Color.BLACK);
brick.setFilled(true);
brick.setColor(Color.BLACK);
add(brick);
}
// @Override
public void run() {
getMenuBar().setVisible(false);
addMouseListeners();
addPaddle();
addBricks();
o = addBall();
moveBall(o);
}
}