Java 突破游戏中只有一块砖块消失

Java 突破游戏中只有一块砖块消失,java,collision-detection,breakout,Java,Collision Detection,Breakout,我是Java新手,从YouTube上的斯坦福讲座中学习 所以我试着把他们的作业改成a,到目前为止还不错。我有我所有的砖块、球和桨,包括游戏的机械原理,但是当我运行游戏时,当被球击中时,只有一块砖块可以被移除。看见该砖块恰好是添加到画布的最后一块砖块 球只是飞过所有其他砖块,没有任何效果。相关代码如下 我是否缺少一些关于getElementAt的重要知识?我感觉getCollidingObject没有分配给collider,这使得碰撞检测出错。我希望有人能在这方面给我启发 private void

我是Java新手,从YouTube上的斯坦福讲座中学习

所以我试着把他们的作业改成a,到目前为止还不错。我有我所有的砖块、球和桨,包括游戏的机械原理,但是当我运行游戏时,当被球击中时,只有一块砖块可以被移除。看见该砖块恰好是添加到画布的最后一块砖块

球只是飞过所有其他砖块,没有任何效果。相关代码如下

我是否缺少一些关于getElementAt的重要知识?我感觉getCollidingObject没有分配给collider,这使得碰撞检测出错。我希望有人能在这方面给我启发

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;
    }
}