Breakout Game in Java does not pass boolean after calling remove () method

I follow CS106A lectures online and complete assignments. I was stuck for several days, although in a breakthrough game, because I can not understand her behavior.

Basically, I created the environment, bricks, ball, paddle, edges, and I can make the ball bounce in the environment. I can even make the ball bounce off the bricks, and I can even remove the bricks. But I can’t make the ball bounce off the bricks and at the same time remove the bricks.

If you look in my code, you will see that I have a method for changing the direction of the ball. This method takes a boolean from my method, which checks to see if the ball has collided with any of the objects in the environment. If I do not turn on the remove () method, the ball will bounce off the bricks as expected. If I turn on this method, the ball will remove the bricks, but does not bounce from them. This indicates that the code is being read and returns a logical value, but the value does not change the direction of the ball.

/* * File: Breakout.java * ------------------- * Name: * Section Leader: * * This file will eventually implement the game of Breakout. */ import java.awt.Color; import java.awt.event.MouseEvent; import acm.graphics.GArc; import acm.graphics.GLine; import acm.graphics.GObject; import acm.graphics.GOval; import acm.graphics.GRect; import acm.program.GraphicsProgram; import acm.util.RandomGenerator; 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; /** Number of turns */ /** private static final int NTURNS = 3;*/ /* Method: run() */ /** Runs the Breakout program. */ public void run() { init(); createBall(); createSides(); createBlocks(); createPaddle(); addMouseListeners(); waitForClick(); while (BALL.getY() <= HEIGHT){ play(); } } public void init(){ setSize(500,700); } private void createBlocks(){ int BRICKS = 0; int ROWS = 0; while (ROWS != NBRICK_ROWS) { while (BRICKS != NBRICKS_PER_ROW){ GRect BRICK = new GRect (BRICK_WIDTH, BRICK_HEIGHT); BRICK.setLocation((BRICKS*(BRICK_SEP + BRICK_WIDTH)+BRICK_SEP), BRICK_Y_OFFSET + (ROWS*(BRICK_HEIGHT + BRICK_SEP))); BRICK.setFilled(true); if (ROWS == 0 || ROWS == 1){ BRICK.setColor(Color.RED); BRICK.setFilled(true);} else if (ROWS == 2 || ROWS == 3) { BRICK.setColor(Color.ORANGE); } else if (ROWS == 4 || ROWS == 5){ BRICK.setColor(Color.YELLOW); } else if (ROWS == 6 || ROWS == 7){ BRICK.setColor(Color.GREEN); } else if (ROWS == 8 || ROWS == 9){ BRICK.setColor(Color.CYAN); } add(BRICK); BRICKS++; } ROWS++; BRICKS = 0; } } private void createSides(){ add(rightSide); add(leftSide); add(topSide); add(bottomSide); } private void createPaddle(){ PADDLE.setFilled(true); add(PADDLE, WIDTH/2 - (PADDLE_WIDTH/2), HEIGHT - PADDLE_Y_OFFSET); } private void createBall(){ BALL.setFilled(true); BALL.setLocation(WIDTH/2 - 18, HEIGHT/2); add(BALL); } private void play(){ /* Add Title Text or Lives or Score */ ballMovement(); } private void ballMovement(){ BRICK_COUNT = (NBRICKS_PER_ROW*NBRICK_ROWS); while (BRICK_COUNT != 0){ BALL.move(ballXVelocity(), ballYVelocity()); pause(5); checkXCollision(); checkYCollision(); } } public int ballXVelocity(){ boolean x = checkXCollision(); if (x == true){ BALL_X_VELOCITY = -INITIAL_X_VELOCITY; INITIAL_X_VELOCITY = BALL_X_VELOCITY; } else {BALL_X_VELOCITY = INITIAL_X_VELOCITY;} return BALL_X_VELOCITY; } public int ballYVelocity(){ boolean y = checkYCollision(); if (y == true){ BALL_Y_VELOCITY = -INITIAL_Y_VELOCITY; INITIAL_Y_VELOCITY = BALL_Y_VELOCITY; } else {BALL_Y_VELOCITY = INITIAL_Y_VELOCITY;} return BALL_Y_VELOCITY; } private boolean checkXCollision(){ double ballX = BALL.getX(); double ballY = BALL.getY(); GObject colObjLeft = getElementAt(ballX, ballY - BALL_RADIUS); GObject colObjRight = getElementAt(ballX + BALL_RADIUS*2, ballY- BALL_RADIUS); if (ballX <= 0 || ballX + (BALL_RADIUS*2) >= APPLICATION_WIDTH){ return true; } else if (colObjLeft != null){ return true; } else if (colObjRight != null){ return true; } else {return false;} } private boolean checkYCollision(){ double ballX = BALL.getX(); double ballY = BALL.getY(); GObject colObjTop = getElementAt(ballX+ BALL_RADIUS, ballY - 1); GObject colObjBot = getElementAt(ballX + BALL_RADIUS, ballY + (BALL_RADIUS*2) + 1); if(colObjBot == PADDLE){ return true; } else if (ballY <= 0){ return true; } else if (colObjTop != null && colObjTop != BALL){ remove(colObjTop); return true; } else if (colObjBot != null && colObjBot != PADDLE && colObjBot != BALL){ remove(colObjBot); return true; } else {return false;} } public void mouseMoved(MouseEvent e){ if (e != null){ int x = e.getX(); PADDLE.setLocation(x - (PADDLE_WIDTH/2), HEIGHT - PADDLE_Y_OFFSET); } } /*public void paddleLocation(dx,dy);*/ /*int x = */ public GRect PADDLE = new GRect(PADDLE_WIDTH, PADDLE_HEIGHT); private GArc BALL = new GArc(BALL_RADIUS*2, BALL_RADIUS*2, 0,360); /*private GOval BALL = new GOval(BALL_RADIUS*2, BALL_RADIUS*2);*/ private int BRICK_COUNT; private int BALL_Y_VELOCITY; private int BALL_X_VELOCITY; private int INITIAL_Y_VELOCITY = 1; private RandomGenerator rgen = RandomGenerator.getInstance(); private int INITIAL_X_VELOCITY = rgen.nextInt(2); private GLine rightSide = new GLine (WIDTH, 0, WIDTH, HEIGHT ); private GLine leftSide = new GLine (0, 0, 0, HEIGHT); private GLine topSide = new GLine (0, 0, WIDTH, 0); private GLine bottomSide = new GLine (0, HEIGHT, WIDTH, HEIGHT); } 
+6
source share
2 answers

It looks like your extra calls to checkXCollision and checkYCollision are a problem.

You call them directly as part of ballMovement , and each of them is also called inside Velocity methods.

To get the parameters for Ball.move , you call the Velocity methods, which check for a collision and remove the brick. But, immediately after moving the ball, you check for a collision and delete again. Thus, the next time ballMovement starts, the bricks are already removed, and collision detection inside Velocity methods does not work.

Since you are not doing anything with collision return values ​​in ballMovement , you probably don't need it.

+2
source

Welcome to SO, the big first question.

 while (BRICK_COUNT != 0){ BALL.move(ballXVelocity(), ballYVelocity()); pause(5); checkXCollision(); checkYCollision(); } 

I think the error lies in calling check*Collision() in your main loop and in your ball*Velocity() methods.

If a collision is found in one of the ball*Velocity() methods, then the brick is removed, the course is canceled and it seems beautiful.

But if a collision is found in direct calls to check*Collision() , then you cannot change direction.

But I am afraid that the correction will be more than just deleting these two lines. (But give it a shot. :) What happens when a ball collides in a corner, both X and Y ? I think the fact is that you check the speed of the ball in two different functions, possibly changing directions in two different functions, and not transferring the knowledge between them, that your collision code when the ball goes into the corner is incorrect. ( checkXCollision() called through ballXVelocity() can remove a brick that checkYCollision() called through ballYVelocity() needs to determine if it needs to change direction.)

You might want to rewrite the functions to calculate X and Y collisions at the same time, so you can remove one or two bricks if necessary.

Hope this helps.

+1
source

Source: https://habr.com/ru/post/885594/


All Articles