2009-08-21 15 views
6

Estoy tomando una introducción a la programación en línea. Sin embargo, estoy atrapado en una tarea.Java Breakout juego saliendo demasiado pronto

La tarea es escribir un juego de ruptura. He escrito con éxito el 97% del juego. Sin embargo, el juego se detiene antes de que se eliminen todos los ladrillos. A veces quedan 4 ladrillos, algunas veces 11. El programa está diseñado para detenerse cuando el marcador llega al punto en el que desaparecieron todos los ladrillos, por lo que debe llegar a ese punto antes.

¿Qué estoy haciendo mal?

Editar: código en línea. y reformulado la pregunta

/* 
* File: Breakout.java 
* ------------------- 
* Name:Alex Godin 
* 
* 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.*; 

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; 

/**pause time*/ 
    private static final int PAUSE_TIME = 3; 

/**THE VALUE OF EACH BRICK*/ 
    private static final int BRICKVAL = 10; 

/** ivar holding the ball*/ 
    private GOval ball; 

/**The current row(for setup)*/ 
    private static int rownum = 0; 

/**The paddle*/ 
    private static GRect paddle = new GRect(PADDLE_WIDTH, PADDLE_HEIGHT); 

/**The velocity*/ 
    private static double vx, vy; 

/**the random generator*/ 
    private RandomGenerator rgen = RandomGenerator.getInstance(); 

/**bricks remaining*/ 
    private static int bricks = NBRICKS_PER_ROW * NBRICK_ROWS; 

/**the score int*/ 
    private static int scoreINT = 0; 

/**livesRemaining*/ 
    private static int livesINT = NTURNS; 

/**score label*/ 
    private static GLabel score = new GLabel("Score:" + scoreINT,0,0); 

/**lives label*/ 
    GLabel lives = new GLabel("lives :" + livesINT,0,0); 

/* Method: run() */ 
/** Runs the Breakout program */ 
    public void run() { 
     scoreAndLives(); 
     setUpBricks(); 
     paddle(); 
     addMouseListeners(); 
     addKeyListeners(); 
     vx = rgen.nextDouble(1.0, 3.0); 
     ball(); 
     move(); 
    } 

/**adds a score and life counter*/ 
    private void scoreAndLives(){ 
     score(); 
     lives(); 
    } 

/**adds a score counter*/ 
    private void score(){ 
     score.setLocation(7,7 + score.getHeight()); 
     score.setColor(Color.RED); 
     score.setFont(new Font("Serif", Font.BOLD, 24)); 
     add(score); 
    } 

/**adds a life counter*/ 
    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); 
    } 

/**designs the brick */ 
    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; 
    } 

/**sets up the bricks*/ 
    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; 
     } 
    } 

/**initializes the paddle*/ 
    private void paddle(){ 
     int xCenter = WIDTH/2 - PADDLE_WIDTH/2; 
     paddle.setFilled(true); 
     add(paddle, xCenter, HEIGHT-PADDLE_Y_OFFSET); 
    } 

/**moves the paddle*/ 
    public void mouseMoved(MouseEvent e){ 
     int x = e.getX(); 
     if(x < WIDTH-PADDLE_WIDTH){ 
     paddle.setLocation(x, APPLICATION_HEIGHT - PADDLE_Y_OFFSET); 
     } 
    } 

/**sets up the ball*/ 
    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; 
    } 

/**the animation*/ 
    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; 
      } 
     } 
    } 

/**Checks for colisions with the wall*/ 
    private void checkWallColisions(){ 
     if(xWallCollision() == true){ 
     xColide(); 
     } 
     if(yWallCollision() == true){ 

     yColide(); 
     }   

    } 

/**what to do in case of a x collision*/ 
    private void xColide(){ 
     if(vx>0){ 
     vx = -1 * rgen.nextDouble(1.0, 3.0); 
     }else{ 
     vx = rgen.nextDouble(1.0, 3.0); 
     } 
    } 

/**what to do in case of a y collision*/ 
    private void yColide(){ 
     if(vx>0){ 
     vx = rgen.nextDouble(1.0, 3.0); 
     }else{ 
     vx = -1 * rgen.nextDouble(1.0, 3.0); 
     } 
     vy=-vy;  
    } 

/**checks for an x wall colision*/ 
    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; 
     } 
    } 

/**checks for a y wall colision*/ 
    private boolean yWallCollision(){ 
     if(ball.getY() > HEIGHT - BALL_RADIUS*2){ 
     return true; 
     }if(ball.getY() < 0){ 
     return true; 
     }else{ 
     return false; 
     } 
    } 

/**gets coliders*/ 
    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; 
     } 
    } 

/**checks for brick and paddle colisions*/ 
    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); 
     } 
    } 
} 

puedo conseguir que la pelota rebote en torno embargo el bucle se escapa antes de que todos los ladrillos se han eliminado y la bola se detiene rebote. El ciclo está configurado para escapar cuando el puntaje alcanza el punto en el que todos los ladrillos desaparecerán. Sin embargo, está llegando a ese punto demasiado temprano.

/**the animation*/ 
private void move(){ 
     if (rgen.nextBoolean(0.5)) vx = -vx; 
       while(true){ 
         checkCollisions(); 
         ball.move(vx, vy); 
         checkWallColisions(); 
         pause(PAUSE_TIME); 
         //where i'm having issues - the loop is set to escape when the score reaches the point at which all the bricks will be gone but the score is reaching that point too early 
         if(scoreINT == bricks * BRICKVAL){ 
           break; 
         } 
       } 
} 

/**gets coliders*/ 
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; 
     } 
} 

/**checks for brick and paddle colisions*/ 
private void checkCollisions(){ 
     GObject colider = getColidingObject(); 
     if(colider == paddle){ 
       yColide(); 
     }else if(colider == lives || colider == score){}else if(colider != null){ 
       remove(colider); 
       yColide(); 
     } 
} 
+10

Bienvenido, Alex. Me alegra ver que alguien de tu edad se interesa en la programación. Desafortunadamente, tengo que disuadirlo de pegar toda su aplicación para su revisión. En cambio, si sospecha que hay algo mal con su método de recuento, debe volver a revisarlo y formular preguntas específicas sobre su implementación. ¡Continúa con el buen trabajo y espero verte más! – Sampson

+1

En realidad, me gustaría decir que creo que lo que hizo fue perfecto. Realmente no es difícil desplazarse por el código de la aplicación, y la gente lo usó para responder a su pregunta. Lo identificaste como tarea (o al menos eso espero) y no le pediste a las personas que hicieran cosas sin suficiente información o una pregunta mal formada. Quizás me perdí la historia, no sé por qué la gente votó para cerrarla, es una pregunta válida y bien hecha. Bienvenido. –

Respuesta

12

¿Está utilizando un IDE como Netbeans o Eclipse para escribir este juego? Si es así, puede establecer algunos puntos de interrupción en su código y ejecutarlo en modo de depuración para intentar descubrir qué está sucediendo.

Supongo que hay un método que verifica si el puntaje es cero y anula el programa. Ponga un punto de interrupción en ese método y ejecute la aplicación: una vez que se alcanza el punto de interrupción, puede usar Relojes para observar el estado de su programa cuando se cierre.

¿Ha comprobado que el programa está saliendo limpiamente? ¿Definitivamente es un puntaje cero que lo apaga? Se podría generar una excepción que está cancelando su aplicación.

Además, si eres nuevo en programación, entonces la depuración es una muy buena habilidad para aprender.

+1

+1 para enseñarle a un programador cómo pescar ;-) –

17

En su método setUpBricks, parece que está creando NBRICK_ROWS * (NBRICKS_PER_ROW + 1) ladrillos. Pero en su método move, solo verifica NBRICKS_PER_ROW * NBRICK_ROWS ladrillos.

+0

+1 para atravesar grandes porciones de código. –

Cuestiones relacionadas