我正在尝试通过在线跟随CS106a课程学习Java。
目前,我已经达到了突破性的极限,并且在Bug方面遇到了一些麻烦
我还没有完全完成它,但是我想先解决这些问题,然后再继续。
问题1:
当球与砖块碰撞时,它们似乎并不总是从画布上移走。
有时,砖会在第二次碰撞时被移除。但是有一排(黄砖)对球的碰撞根本没有反应。
问题2:
可以通过拖动鼠标来移动我的桨。唯一的问题是。砖块也可以像桨一样移动。
我知道这与这段代码有关
gobj = getElementAt(lastX, lastY);
如果我将其完全移除,则砖块将不再移动。很好但我还是
无论我单击并拖动到哪里,都能移动桨叶。
谁能给我一个提示,以便我纠正错误?
这是我的下面的代码。
谢谢
/*
* File: Breakout.java
* -------------------
* This file will eventually implement the game of Breakout.
*/
import acm.graphics.*;
import acm.program.*;
import acm.util.*;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import org.omg.CORBA.PUBLIC_MEMBER;
public class breakout extends GraphicsProgram {
/** 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 = 8;
/** 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;
/** 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 int DELAY = 50;
private static final double X_START = WIDTH / 2;
private static final double Y_START = 450;
public void run() {
world();
play();
}
private void ball() {
ball = new GOval(X_START, Y_START, BALL_RADIUS, BALL_RADIUS);
ball.setFillColor(Color.BLACK);
ball.setFilled(true);
add(ball);
}
private void paddle() {
paddle = new GRect(100, 500, PADDLE_WIDTH, PADDLE_HEIGHT);
paddle.setColor(Color.BLACK);
paddle.setFilled(true);
add(paddle);
}
private void brick(int x, int y, Color c) {
GRect brick = new GRect(x, y, BRICK_WIDTH, BRICK_HEIGHT);
brick.setColor(getBackground());
brick.setFillColor(c);
brick.setFilled(true);
add(brick);
}
private void brickRow(int x, int y, Color c) {
x = BRICK_SEP / 2;
y += BRICK_Y_OFFSET;
for (int i = 0; i < NBRICKS_PER_ROW; i++) {
brick(x, y, c);
x += BRICK_WIDTH + BRICK_SEP;
}
}
private void world() {
//initialize x and y position for the rows of bricks
int x = 0;
int y = 0;
// set starting color for first row
Color c = Color.red;
paddle();
//create 2 rows of bricks and switch colors
for (int i = 0; i < NBRICK_ROWS; i++) {
if (i <= 1) {
c = Color.ORANGE;
} else if (i > 1 && i <= 3) {
c = Color.YELLOW;
} else if (i > 3 && i <= 5) {
c = Color.GREEN;
} else if (i > 5 && i <= 7) {
c = Color.CYAN;
}
brickRow(x, y, c);
y += BRICK_HEIGHT + BRICK_SEP;
}
}
private void moveBall() {
ball.move(xVel, yVel);
}
public void mousePressed(MouseEvent e) {
lastX = e.getX();
lastY = e.getY();
gobj = getElementAt(lastX, lastY);
}
public void mouseDragged(MouseEvent e) {
if (paddle != null) {
paddle.move(e.getX() - lastX, getY());
lastX = e.getX();
lastY = e.getY();
}
//constrain paddle movement
if (paddle.getX() < 0){
paddle.setLocation(0, 500);
}else if (paddle.getX()+BRICK_WIDTH > WIDTH ){
paddle.setLocation(WIDTH-BRICK_WIDTH, 500);
}
}
private void checkForCollision() {
// ball collission with walls
if (ball.getY() > getHeight() - BALL_RADIUS
|| ball.getY() < 0 + BALL_RADIUS) {
yVel = -yVel;
} else if (ball.getX() > getWidth() - BALL_RADIUS
|| ball.getX() < 1 + BALL_RADIUS) {
xVel = -xVel;
// ball collission with paddle
} else if (getElementAt(ball.getX() + BALL_RADIUS, ball.getY()
+ BALL_RADIUS) == paddle) {
yVel = -yVel;
// check for collision with bricks to remove them but ignore collision with paddle
} else if (getElementAt(ball.getX(), ball.getY()) != null
&& getElementAt(ball.getX(), ball.getY()) != paddle) {
remove(getCollidingObject(ball.getX(), ball.getY()));
yVel = -yVel;
} else if (getElementAt(ball.getX() + BALL_RADIUS, ball.getY()
+ BALL_RADIUS) != null
&& getElementAt(ball.getX() + BALL_RADIUS, ball.getY()
+ BALL_RADIUS) != paddle) {
remove(getCollidingObject(ball.getX() + BALL_RADIUS, ball.getY()
+ BALL_RADIUS));
yVel = -yVel;
} else if (getElementAt(ball.getX() + BALL_RADIUS, ball.getY()
+ BALL_RADIUS) != null
&& getElementAt(ball.getX() + BALL_RADIUS, ball.getY()
+ BALL_RADIUS) != paddle) {
remove(getCollidingObject(ball.getX() + BALL_RADIUS, ball.getY()
+ BALL_RADIUS));
yVel = -yVel;
} else if (getElementAt(ball.getX(), ball.getY() + BALL_RADIUS) != null
&& getElementAt(ball.getX(), ball.getY() + BALL_RADIUS) != paddle) {
remove(getCollidingObject(ball.getX(), ball.getY() + BALL_RADIUS));
yVel = -yVel;
}
}
private void play() {
addMouseListeners();
ball();
while (true) {
checkForCollision();
moveBall();
pause(DELAY);
}
}
private GObject getCollidingObject(double x, double y) {
return getElementAt(x, y);
}
private double lastX;
private double lastY;
private double xVel = 5;
private double yVel = 15;
private GOval ball;
private GRect paddle;
private GObject gobj;
}
最佳答案
为什么在讲义19中不使用建议的方法:
private GObject getCollidingObject()
也使用对撞机:
GObject collider = getCollidingObject();
首先,将您与墙壁碰撞和(与砖块划桨)游戏元素碰撞的条件分为两种单独的方法,以简化
else if
级联(分解,我想您知道这是什么意思)。您只有两个对象需要担心paddle
和bricks
,因此您只需要比较(collider == paddle)
和collider != null
。同样,您在比较中仅使用半径,但应使用直径(2 *半径)。玩得开心 :)