Java 突破游戏中只有一块砖块消失
我是Java新手,从YouTube上的斯坦福讲座中学习 所以我试着把他们的作业改成a,到目前为止还不错。我有我所有的砖块、球和桨,包括游戏的机械原理,但是当我运行游戏时,当被球击中时,只有一块砖块可以被移除。看见该砖块恰好是添加到画布的最后一块砖块 球只是飞过所有其他砖块,没有任何效果。相关代码如下 我是否缺少一些关于getElementAt的重要知识?我感觉getCollidingObject没有分配给collider,这使得碰撞检测出错。我希望有人能在这方面给我启发Java 突破游戏中只有一块砖块消失,java,collision-detection,breakout,Java,Collision Detection,Breakout,我是Java新手,从YouTube上的斯坦福讲座中学习 所以我试着把他们的作业改成a,到目前为止还不错。我有我所有的砖块、球和桨,包括游戏的机械原理,但是当我运行游戏时,当被球击中时,只有一块砖块可以被移除。看见该砖块恰好是添加到画布的最后一块砖块 球只是飞过所有其他砖块,没有任何效果。相关代码如下 我是否缺少一些关于getElementAt的重要知识?我感觉getCollidingObject没有分配给collider,这使得碰撞检测出错。我希望有人能在这方面给我启发 private void
private void addBallMotion(){
// y component of starting velocity; pixels per second
vy = 3.0;
/* x component of starting velocity; pixels per second
* which ranges according to the random generator
* can be negative or positive, ball can go left or right with equal chances
*/
vx = rgen.nextDouble(1.0, 3.0);
if (rgen.nextBoolean(0.5)){
vx = -vx;
}
while (true){
ball.move(vx, vy);
checkCollision();
pause(FPS);
}
}
private void checkCollision(){
checkWallCollision();
checkBrickAndPaddleCollision();
}
private void checkWallCollision(){
//checks for left or right collision
if ( (ball.getX() < leftBounds.getX() ) || (ball.getX() + BALL_RADIUS * 2 > rightBounds.getX()) ){
vx = -vx;
}
//checks for top or bottom collision
if ( (ball.getY() < topBounds.getY() ) || (ball.getY() + BALL_RADIUS * 2 > bottomBounds.getY()) ){
vy = -vy;
}
}
private void checkBrickAndPaddleCollision(){
GObject collider = getCollidingObject();
if (collider == brick){
remove(collider);
vy = -vy;
}
if (collider == paddle){
vy = -vy;
}
}
//check for collision at the 4 edges of the ball
//starting with the left and going clockwise
private GObject getCollidingObject(){
GObject ballLeft= getElementAt (ball.getX() - 1, ball.getY() + BALL_RADIUS);
GObject ballRight= getElementAt (ball.getX() + BALL_RADIUS * 2 + 1, ball.getY() + BALL_RADIUS);
GObject ballTop = getElementAt (ball.getX() + BALL_RADIUS * 2, ball.getY() - 1);
GObject ballBottom= getElementAt (ball.getX() + BALL_RADIUS, ball.getY() + BALL_RADIUS * 2 + 1);
if (ballLeft != null){
return (ballLeft);
}
else if (ballTop != null){
return (ballTop);
}
else if (ballRight != null){
return (ballRight);
}
else if (ballBottom != null){
return (ballBottom);
}
return (null);
}
private GRect paddle; // creates a paddle that only moves linearly according to mouses' x coordinate
private GRect brick;
private GOval ball;
private double vx, vy; // x and y components of the ball's velocity
//private GObject collider;
private void addBallMotion(){
//起始速度的y分量;像素/秒
vy=3.0;
/*开始速度的x分量;像素/秒
*哪些范围根据随机生成器而定
*可以是负数或正数,球可以向左或向右移动,机会均等
*/
vx=rgen.nextDouble(1.0,3.0);
if(rgen.nextBoolean(0.5)){
vx=-vx;
}
while(true){
球移动(vx,vy);
检查碰撞();
暂停(FPS);
}
}
私有void checkCollision(){
checkWallCollision();
检查是否存在碰撞();
}
私有void checkWallCollision(){
//检查左侧或右侧碰撞
如果((ball.getX()rightbunds.getX())){
vx=-vx;
}
//检查顶部或底部碰撞
如果((ball.getY()bottomBounds.getY())){
vy=-vy;
}
}
私有无效检查冲突(){
GObject collider=getCollidingObject();
如果(碰撞器==砖){
移除(对撞机);
vy=-vy;
}
如果(碰撞器==桨叶){
vy=-vy;
}
}
//检查球的4个边缘是否有碰撞
//从左边开始,顺时针走
私有GObject getCollidingObject(){
GObject-ballLeft=getElementAt(ball.getX()-1,ball.getY()+ball_半径);
GObject-ballRight=getElementAt(ball.getX()+ball_半径*2+1,ball.getY()+ball_半径);
GObject ballTop=getElementAt(ball.getX()+ball_半径*2,ball.getY()-1);
GObject ballBottom=getElementAt(ball.getX()+ball_半径,ball.getY()+ball_半径*2+1);
如果(ballLeft!=null){
返回(左);
}
else if(ballTop!=null){
返回(球头);
}
else if(ballRight!=null){
返回(右键);
}
else if(球底!=null){
返回(球底);
}
返回(空);
}
私人格雷特桨;//创建仅根据鼠标的x坐标线性移动的挡板
私用砖;
私人政府舞会;
专用双vx,vy;//球速度的x和y分量
//私人对撞机;
以下是整个计划:
import acm.graphics.*;
import acm.program.*;
import acm.util.*;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
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 = 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;
/** Offset of the top brick row from the top */
private static final int BRICK_Y_OFFSET = 70;
/** Offset of the side bricks from the sides of game window */
private static final int BRICK_X_OFFSET = ((WIDTH - NBRICKS_PER_ROW * (BRICK_WIDTH + BRICK_SEP) + BRICK_SEP) / 2);
/** Number of turns */
private static final int NTURNS = 3;
/** Number of frames per second */
private static final int FPS = 1;
/* Method: run() */
/** Runs the Breakout program. */
public void run() {
addMouseListeners();
addWorld();
// runGame();
}
private void addWorld(){
setSize (APPLICATION_WIDTH, APPLICATION_HEIGHT);
addPlayingBox();
addBricks();
addPaddle();
addBall();
// addCounter();
}
//adds the bound area onto screen
private void addPlayingBox(){
topBounds = new GLine (0, 0, WIDTH, 0);
bottomBounds = new GLine (0, HEIGHT, WIDTH, HEIGHT);
leftBounds = new GLine (0, 0, 0, HEIGHT);
rightBounds = new GLine (WIDTH, 0, WIDTH, HEIGHT);
add (topBounds);
add (bottomBounds);
add (leftBounds);
add (rightBounds);
}
private void addBricks(){
for (int i = 0; i < NBRICK_ROWS; i++){
int y = BRICK_Y_OFFSET + (i * (BRICK_HEIGHT + BRICK_SEP));
for (int j = 0; j < NBRICKS_PER_ROW; j++){
int x = (BRICK_X_OFFSET) + (j * (BRICK_WIDTH + BRICK_SEP));
brick = new GRect (x, y, BRICK_WIDTH, BRICK_HEIGHT );
colorBrick(brick, i);
add (brick);
}
}
}
// every consecutive 2 rows are colored the same
private void colorBrick(GRect brick, int rowNumber){
brick.setFilled (true);
switch (rowNumber + 1) {
case 1: case 2: brick.setColor(Color.red);
break;
case 3: case 4: brick.setColor(Color.orange);
break;
case 5: case 6: brick.setColor(Color.yellow);
break;
case 7: case 8: brick.setColor(Color.green);
break;
case 9: case 10:brick.setColor(Color.cyan);
break;
}
}
//adds paddle to screen
private void addPaddle(){
paddle = new GRect (PADDLE_WIDTH, PADDLE_HEIGHT);
paddle.setFilled(true);
paddle.setColor (Color.BLACK);
add (paddle);
}
//creates motion for the paddle according to mouse movement
public void mouseMoved(MouseEvent e){
paddle.setLocation ((e.getX() - PADDLE_WIDTH / 2), (double) (HEIGHT - PADDLE_Y_OFFSET));
/* checks if the paddle within the playing area
* if not the paddles will stay at the extremities*/
if ( paddle.getX() > (WIDTH - PADDLE_WIDTH)){
paddle.setLocation((double) (WIDTH - PADDLE_WIDTH), (double) (HEIGHT - PADDLE_Y_OFFSET));
}
if ( paddle.getX() < 0){
paddle.setLocation((double) 0, (double) (APPLICATION_HEIGHT - PADDLE_Y_OFFSET));
}
}
private void addBall(){
ball = new GOval (((WIDTH - BALL_RADIUS * 2) / 2), ((HEIGHT - BALL_RADIUS * 2) / 2),
BALL_RADIUS * 2, BALL_RADIUS * 2);
ball.setFilled(true);
ball.setColor(Color.BLACK);
add (ball);
addBallMotion();
}
private void addBallMotion(){
// y component of starting velocity; pixels per second
vy = 3.0;
/* x component of starting velocity; pixels per second
* which ranges according to the random generator
* can be negative or positive, ball can go left or right with equal chances
*/
vx = rgen.nextDouble(1.0, 3.0);
if (rgen.nextBoolean(0.5)){
vx = -vx;
}
while (true){
ball.move(vx, vy);
checkCollision();
pause(FPS);
}
}
private void checkCollision(){
checkWallCollision();
checkBrickAndPaddleCollision();
}
private void checkWallCollision(){
//checks for left or right collision
if ( (ball.getX() < leftBounds.getX() ) || (ball.getX() + BALL_RADIUS * 2 > rightBounds.getX()) ){
vx = -vx;
}
//checks for top or bottom collision
if ( (ball.getY() < topBounds.getY() ) || (ball.getY() + BALL_RADIUS * 2 > bottomBounds.getY()) ){
vy = -vy;
}
}
private void checkBrickAndPaddleCollision(){
GObject collider = getCollidingObject();
if (collider == brick){
remove(collider);
vy = -vy;
}
if (collider == paddle){
vy = -vy;
}
}
//check for collision at the 4 edges of the ball
//starting with the left and going clockwise
private GObject getCollidingObject(){
GObject ballLeft= getElementAt (ball.getX() - 1, ball.getY() + BALL_RADIUS);
GObject ballRight= getElementAt (ball.getX() + BALL_RADIUS * 2 + 1, ball.getY() + BALL_RADIUS);
GObject ballTop = getElementAt (ball.getX() + BALL_RADIUS * 2, ball.getY() - 1);
GObject ballBottom= getElementAt (ball.getX() + BALL_RADIUS, ball.getY() + BALL_RADIUS * 2 + 1);
if (ballLeft != null){
return (ballLeft);
}
else if (ballTop != null){
return (ballTop);
}
else if (ballRight != null){
return (ballRight);
}
else if (ballBottom != null){
return (ballBottom);
}
return (null);
}
private GRect paddle; // creates a paddle that only moves linearly according to mouses' x coordinate
private GRect brick;
private GOval ball;
private double vx, vy; // x and y components of the ball's velocity
private RandomGenerator rgen = RandomGenerator.getInstance();
//private GObject collider;
private GLine topBounds; // creates a bounding box that is the playing area
private GLine bottomBounds;
private GLine leftBounds;
private GLine rightBounds;
}
导入acm.graphics.*;
导入acm.程序。*;
导入acm.util.*;
导入java.applet.*;
导入java.awt.*;
导入java.awt.event.*;
公共类突破扩展图形程序{
/**应用程序窗口的宽度和高度(像素)*/
公共静态最终整数应用程序\u宽度=400;
公共静态最终int应用程序_高度=600;
/**游戏板的尺寸(通常相同)*/
私有静态最终整型宽度=应用程序宽度;
专用静态最终整型高度=应用程序高度;
/**桨叶的尺寸*/
专用静态最终int桨_宽度=60;
专用静态最终内桨高度=10;
/**桨叶从底部向上的偏移量*/
专用静态最终int桨_Y_偏移=30;
/**每排砖的数量*/
每行专用静态最终整容数=10;
/**砖排数*/
私有静态final int NBRICK_ROWS=10;
/**砖与砖之间的分隔*/
专用静态最终整块砖_SEP=4;
/**砖宽*/
专用静态最终整型砖宽度=
(宽度-(每排砖-1)*每排砖)/n每排砖;
/**砖高*/
专用静态最终整砖高度=8;
/**球的半径(以像素为单位)*/
私人静态最终整数球半径=10;
/**顶部砖行相对于顶部的偏移量*/
专用静态最终整块砖Y偏移=70;
/**侧砖从游戏窗口侧面的偏移量*/
私有静态最终整块砖X砖偏移=((宽度-每行砖数*(砖宽+砖厚+砖厚)/2);
/**圈数*/
专用静态最终整数NTURNS=3;
/**每秒帧数*/
专用静态最终整数FPS=1;
/*方法:run()*/
/**运行突破计划*/
公开募捐{
addMouseListeners();
addWorld();
//runGame();
}
私有虚拟世界(){
设置尺寸(应用宽度、应用高度);
addPlayingBox();
addBricks();
addpaile();
addBall();
//addCounter();
}
//将绑定区域添加到屏幕上
私有void addPlayingBox(){
topBounds=新的GLine(0,0,宽度,0);
bottomBounds=新GLine(0,高度,宽度,高度);
leftBounds=新的GLine(0,0,0,高度);
rightBounds=新GLine(宽度,0,宽度,高度);
添加(上界);
添加(底部边界);
添加(左边界);
添加(右边界);
}
私有无效addBricks(){
对于(int i=0;iprivate void addBricks(){
for (int i = 0; i < NBRICK_ROWS; i++){
int y = BRICK_Y_OFFSET + (i * (BRICK_HEIGHT + BRICK_SEP));
for (int j = 0; j < NBRICKS_PER_ROW; j++){
int x = (BRICK_X_OFFSET) + (j * (BRICK_WIDTH + BRICK_SEP));
brick = new GRect (x, y, BRICK_WIDTH, BRICK_HEIGHT );
colorBrick(brick, i);
add (brick);
}
}
}
int x;
x = 5;
x = 6;
x = 8;
// x is 8 now
ArrayList<GRect> bricks;
GRect brick;
bricks.add(new GRect (x, y, BRICK_WIDTH, BRICK_HEIGHT));
brick = new GRect (x, y, BRICK_WIDTH, BRICK_HEIGHT );
if (collider == brick) {
remove(collider);
vy = -vy;
}
for(GRect brick : bricks) {
if (collider.equals(brick)) { // Note that you should rather use .equals, instead of == as Aurand stated in his comment
remove(collider);
vy = -vy;
}
}