I take an intro for programming on the Internet. However, I was stuck in one task.
Purpose - to write a breakthrough game. I successfully wrote 97% of the game. However, the game stops before removing all the bricks. Sometimes 4 bricks remain, several times 11. The program is designed to stop when the point counter reaches the point where all the bricks are gone, so it must reach this point earlier.
What am I doing wrong?
Edit: inline code. and rephrased question
import acm.graphics.*; import acm.program.*; import acm.util.*; import java.applet.*; import java.awt.*; import java.awt.event.*; public class Breakout extends GraphicsProgram { public static final int APPLICATION_WIDTH = 400; public static final int APPLICATION_HEIGHT = 600; private static final int WIDTH = APPLICATION_WIDTH; private static final int HEIGHT = APPLICATION_HEIGHT; private static final int PADDLE_WIDTH = 60; private static final int PADDLE_HEIGHT = 10; private static final int PADDLE_Y_OFFSET = 30; private static final int NBRICKS_PER_ROW = 10; private static final int NBRICK_ROWS = 10; private static final int BRICK_SEP = 4; private static final int BRICK_WIDTH = (WIDTH - (NBRICKS_PER_ROW - 1) * BRICK_SEP) / NBRICKS_PER_ROW; private static final int BRICK_HEIGHT = 8; private static final int BALL_RADIUS = 10; private static final int BRICK_Y_OFFSET = 70; private static final int NTURNS = 3; private static final int PAUSE_TIME = 3; private static final int BRICKVAL = 10; private GOval ball; private static int rownum = 0; private static GRect paddle = new GRect(PADDLE_WIDTH, PADDLE_HEIGHT); private static double vx, vy; private RandomGenerator rgen = RandomGenerator.getInstance(); private static int bricks = NBRICKS_PER_ROW * NBRICK_ROWS; private static int scoreINT = 0; private static int livesINT = NTURNS; private static GLabel score = new GLabel("Score:" + scoreINT,0,0); GLabel lives = new GLabel("lives :" + livesINT,0,0); public void run() { scoreAndLives(); setUpBricks(); paddle(); addMouseListeners(); addKeyListeners(); vx = rgen.nextDouble(1.0, 3.0); ball(); move(); } private void scoreAndLives(){ score(); lives(); } private void score(){ score.setLocation(7,7 + score.getHeight()); score.setColor(Color.RED); score.setFont(new Font("Serif", Font.BOLD, 24)); add(score); } private void lives(){ lives.setLocation(WIDTH - lives.getWidth()*2 + 7,7 + lives.getHeight()); lives.setColor(Color.RED); lives.setFont(new Font("Serif", Font.BOLD, 24)); add(lives); } private GRect brickDesign() { GRect brick = new GRect(BRICK_WIDTH, BRICK_HEIGHT); brick.setFilled(true); switch (rownum + 1){ case 1: brick.setColor(Color.RED); break; case 2: brick.setColor(Color.RED); break; case 3: brick.setColor(Color.ORANGE); break; case 4: brick.setColor(Color.ORANGE); break; case 5: brick.setColor(Color.YELLOW); break; case 6: brick.setColor(Color.YELLOW); break; case 7: brick.setColor(Color.GREEN); break; case 8: brick.setColor(Color.GREEN); break; case 9: brick.setColor(Color.CYAN); break; case 10: brick.setColor(Color.CYAN); break; } return brick; } private void setUpBricks(){ int x=0; int y=0; for(int i=0; i<NBRICK_ROWS; i++){ x=0; y=rownum * BRICK_HEIGHT + BRICK_SEP * i + BRICK_Y_OFFSET; for(int j=0; j<NBRICKS_PER_ROW + 1; j++){ add(brickDesign(), x, y); x=(j * BRICK_WIDTH) + (BRICK_SEP * j); } rownum+=1; } } private void paddle(){ int xCenter = WIDTH/2 - PADDLE_WIDTH/2; paddle.setFilled(true); add(paddle, xCenter, HEIGHT-PADDLE_Y_OFFSET); } public void mouseMoved(MouseEvent e){ int x = e.getX(); if(x < WIDTH-PADDLE_WIDTH){ paddle.setLocation(x, APPLICATION_HEIGHT - PADDLE_Y_OFFSET); } } private void ball(){ ball = new GOval( WIDTH/2 - BALL_RADIUS, HEIGHT/2 - BALL_RADIUS, BALL_RADIUS * 2, BALL_RADIUS * 2); ball.setFilled(true); add(ball); vy = 3.0; } private void move(){ if (rgen.nextBoolean(0.5)) vx = -vx; while(true){ ball.move(vx, vy); checkWallColisions(); checkCollisions(); pause(PAUSE_TIME); if(scoreINT == bricks * BRICKVAL){ break; } } } private void checkWallColisions(){ if(xWallCollision() == true){ xColide(); } if(yWallCollision() == true){ yColide(); } } private void xColide(){ if(vx>0){ vx = -1 * rgen.nextDouble(1.0, 3.0); }else{ vx = rgen.nextDouble(1.0, 3.0); } } private void yColide(){ if(vx>0){ vx = rgen.nextDouble(1.0, 3.0); }else{ vx = -1 * rgen.nextDouble(1.0, 3.0); } vy=-vy; } private boolean xWallCollision(){ if(ball.getX() + BALL_RADIUS*2 > WIDTH){ double bally=ball.getY(); ball.setLocation(WIDTH-BALL_RADIUS*2, bally); return true; }else if(ball.getX() < 0){ double bally=ball.getY(); ball.setLocation(0, bally); return true; }else{ return false; } } private boolean yWallCollision(){ if(ball.getY() > HEIGHT - BALL_RADIUS*2){ return true; }if(ball.getY() < 0){ return true; }else{ return false; } } private GObject getColidingObject(){ if(getElementAt(ball.getX(), ball.getY()) != null){ return getElementAt(ball.getX(), ball.getY()); }else if(getElementAt(ball.getX() + BALL_RADIUS *2, ball.getY()) != null){ return getElementAt(ball.getX() + BALL_RADIUS *2, ball.getY()); }else if(getElementAt(ball.getX(), ball.getY() + BALL_RADIUS *2) != null){ return getElementAt(ball.getX(), ball.getY() + BALL_RADIUS *2); }else if(getElementAt(ball.getX() + BALL_RADIUS *2, ball.getY() + BALL_RADIUS *2) != null){ return getElementAt(ball.getX() + BALL_RADIUS *2, ball.getY() + BALL_RADIUS *2); }else{ return null; } } private void checkCollisions(){ GObject colider = getColidingObject(); if(colider == paddle){ yColide(); }else if(colider == lives || colider == score){ }else if(colider != null){ yColide(); remove(colider); scoreINT+=BRICKVAL; score.setLabel("Score:" + scoreINT); } } }
I can make the ball bounce, but the cycle goes out before all the bricks have been removed and the ball stops jumping. The loop goes off when the count reaches the point at which all the bricks will be lost. However, he reached this point too early.
private void move(){ if (rgen.nextBoolean(0.5)) vx = -vx; while(true){ checkCollisions(); ball.move(vx, vy); checkWallColisions(); pause(PAUSE_TIME);