Results 1 to 2 of 2
  1. #1
    jjs
    jjs is offline Member
    Join Date
    Mar 2011
    Posts
    1
    Rep Power
    0

    Default Assist a Beginner's Breakout Code

    Hi everyone, I'm new to Java and to this forum. I've been following along with Stanford's CS106A class online, and wrote the code below (except the imports and constants, which were given by the professor) as part of assignment 3. But this isn't homework; there's no grades or credit. So I'm not looking for an easy answer, only to learn the fundamentals of Java.

    Below is my attempt at the "Breakout" game. It meets the requirements as set by the professor, with one notable bug. Sometimes when the paddle collides with the ball, or the ball with the paddle at some angles, the ball's y-direction seems to change back and forth rapidly, instead of changing once and heading back toward the bricks. It looks like the ball is "stuck" to the paddle for a short amount of time. I believe this happens because my test for a collision checks the four "corners" of the ball -- I believe different corners are hitting the paddle at different times and switching the balls y-direction rapidly. What is the best way to prevent this behavior? Is there a way to make my checkCollision() method inactive for a short amount of time after the last collision?

    More generally, can someone with experience take a look at the code below and give me feedback on how it can be improved? How can this code be more structured, more logical, more readable, better commented? (Likewise, how can this post be more usefully written?) Any feedback is appreciated.

    My intent here is to get some feedback on my work below, and to create a thread that allows future CS106A online followers to compare their code to other products and your expert comments to see how and where I/they could have done better.

    **My tabs and spacing don't seem to show up in the post.


    /*
    * File: Breakout.java
    * --------------------
    * Created to meet the requirements of Assignment 3 of Stanford's CS106A course online.
    */

    import acm.graphics.*;
    import acm.program.*;
    import acm.util.*;
    import java.awt.*;
    import java.awt.event.*;

    public class Breakout extends GraphicsProgram {

    /* divides game into a method to setup the game and a method to play it */
    public void run() {
    setupGame();
    playGame();
    }

    /* setupGame creates game elements: bricks, paddle, and ball */
    public void setupGame(){
    createBricks();
    createPaddle();
    createBall();
    addMouseListeners();
    }

    /* (2) for-loops create the stack of bricks.
    * Outside for-loop counter assigns color to each row of bricks */
    public void createBricks(){
    for (int j = 0; j < NBRICK_ROWS; j++){
    for (int i = 0; i < NBRICKS_PER_ROW; i++){
    GRect brick = new GRect (BRICK_WIDTH, BRICK_HEIGHT);
    brick.setFilled(true);
    if (j < 2){
    brick.setColor(Color.RED);
    brick.setFillColor(Color.RED);
    } else if ((j == 2) || (j == 3)) {
    brick.setColor(Color.ORANGE);
    brick.setFillColor(Color.ORANGE);
    } else if ((j == 4) || (j == 5)) {
    brick.setColor(Color.YELLOW);
    brick.setFillColor(Color.YELLOW);
    } else if ((j == 6) || (j == 7)) {
    brick.setColor(Color.GREEN);
    brick.setFillColor(Color.GREEN);
    } else if ((j == 8) || (j == 9)) {
    brick.setColor(Color.CYAN);
    brick.setFillColor(Color.CYAN);
    }
    add(brick, (BRICK_SEP / 2) + (i * (BRICK_WIDTH + BRICK_SEP)), (BRICK_Y_OFFSET + (j * (BRICK_HEIGHT + BRICK_SEP))));
    }
    }
    }

    /* Creates paddle that starts in the middle of the gamespace*/
    public void createPaddle(){
    paddle = new GRect (PADDLE_WIDTH, PADDLE_HEIGHT);
    paddle.setFilled(true);
    add(paddle, (WIDTH / 2 - PADDLE_WIDTH / 2), (HEIGHT - (PADDLE_Y_OFFSET + PADDLE_HEIGHT)));
    }

    /* Shifts paddle according to x-coordinate of mouse when the cursor is in the window
    * Sets paddle to far left of gamespace if cursor is left of window
    * Sets paddle to the far right of gamespace if cursor is right of the window
    */
    public void mouseMoved(MouseEvent e){
    paddle.move((e.getX()-paddle.getX()) - PADDLE_WIDTH / 2, 0);

    if(paddle.getX() < 0){
    paddle.setLocation(0, (HEIGHT - (PADDLE_Y_OFFSET + PADDLE_HEIGHT)));
    } else if((paddle.getX() + PADDLE_WIDTH) > WIDTH) {
    paddle.setLocation((WIDTH - PADDLE_WIDTH), (HEIGHT - (PADDLE_Y_OFFSET + PADDLE_HEIGHT)));
    }
    }

    /* Creates a ball and positions it in the middle of the window */
    public void createBall(){
    ball = new GOval (BALL_RADIUS * 2, BALL_RADIUS *2);
    ball.setFilled(true);
    add(ball, WIDTH / 2 - BALL_RADIUS, HEIGHT / 2);
    }

    /* Executes game
    * Starts the ball once
    * In every turn while the game is not over, moves the ball then checks for a wall, brick, or paddle
    * When the game is over, shows win or loss */

    public void playGame(){
    startBall();
    while ((checkLastBrick() == false) & (lives > 0)) {
    moveBall();
    checkWallBounce();
    checkCollision();
    }
    if (checkLastBrick() == true){
    showWin();
    } else {
    showLost();
    }
    }

    /* Creates a sign for when the game is won*/
    public void showWin(){
    win = new GLabel("Congratulations! You won!");
    win.setColor(Color.BLUE);
    win.setFont(new Font("Serif", Font.BOLD, 20));
    win.setLocation(WIDTH / 2 - win.getWidth() / 2, HEIGHT / 2 - win.getHeight());
    remove(ball);
    add(win);
    }

    /* Creates a sign for when the game is lost */
    public void showLost(){
    lost = new GLabel("Sorry. You lost.");
    lost.setColor(Color.RED);
    lost.setFont(new Font("Serif", Font.BOLD, 18));
    lost.setLocation(WIDTH / 2 - lost.getWidth() / 2, HEIGHT / 2 - lost.getHeight());
    remove(ball);
    add(lost);
    }

    /*checks to see if there are any more bricks, to see if the game is over */
    public Boolean checkLastBrick(){
    if (brick_counter >= NBRICKS){
    return true;
    } else return false;
    }

    /* Assigns pseudo-random start x-direction for the ball. -1 < vx < 1 not included because sharper angles make more interesting gameplay */
    public void startBall(){
    vx = rgen.nextDouble(1.0, 3.0);
    if (rgen.nextBoolean(0.5)) vx = -vx;
    }

    /* Moves the ball and pauses so the movement can be registered by the player */
    public void moveBall(){
    ball.move(vx, vy);
    ball.pause(12.0);
    }

    /* checks to see if the ball is touching any of the walls.
    * flips x direction for side walls, y direction for top wall
    * counts down a "life," creates and starts a new ball if the ball touches the bottom wall */
    public void checkWallBounce(){
    if (ball.getX() + 2 * BALL_RADIUS >= WIDTH) {
    vx = -vx;
    }
    if (ball.getX() <= 0) {
    vx = -vx;
    }
    if (ball.getY() <= 0) {
    vy = -vy;
    }
    if (ball.getY() - 2* BALL_RADIUS >= HEIGHT) {
    lives--;
    createBall();
    startBall();
    }
    }

    /* checks to see if any 'corner' of the square that delimits the ball touches an object
    * when there is an object, flips the y-direction of the ball
    * when there is brick - the only object that isn't the paddle aside from itself - removes the object and adds to the counter of bricks removed */
    public void checkCollision(){
    if(getElementAt(ball.getX(), ball.getY()) != null){
    GObject collider = getElementAt(ball.getX(), ball.getY());
    vy = -vy;
    if (collider != paddle){
    remove(collider);
    brick_counter++;
    }
    } else if (getElementAt((ball.getX() + 2 * BALL_RADIUS), ball.getY()) != null){
    GObject collider = getElementAt(ball.getX() + 2 * BALL_RADIUS, ball.getY());
    vy = -vy;
    if (collider != paddle){
    remove(collider);
    brick_counter++;
    }
    } else if (getElementAt((ball.getX() + 2 * BALL_RADIUS), ball.getY() + 2 * BALL_RADIUS) != null){
    GObject collider = getElementAt(ball.getX() + 2 * BALL_RADIUS, ball.getY() + 2 * BALL_RADIUS);
    vy = -vy;
    if (collider != paddle){
    remove(collider);
    brick_counter++;
    }
    } else if (getElementAt(ball.getX(), ball.getY() + 2 * BALL_RADIUS) != null){
    GObject collider = getElementAt(ball.getX(), ball.getY() + 2 * BALL_RADIUS);
    vy = -vy;
    if (collider != paddle){
    remove(collider);
    brick_counter++;
    }
    }
    }

    /* Private constants */
    /** 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 - same as application window */
    public static final int WIDTH = APPLICATION_WIDTH;
    public static final int HEIGHT = APPLICATION_HEIGHT;

    /** Dimensions of the paddle */
    public static final int PADDLE_WIDTH = 60;
    public static final int PADDLE_HEIGHT = 10;

    /** Offset of the paddle from the bottom */
    public static final int PADDLE_Y_OFFSET = 50;

    /** Number of bricks per row */
    public static final int NBRICKS_PER_ROW = 10;

    /** Number of rows of bricks */
    public static final int NBRICK_ROWS = 10;

    /** Number of total bricks */
    public static final int NBRICKS = NBRICKS_PER_ROW * NBRICK_ROWS;

    /** Separation between bricks */
    public 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;


    /* private instance variables */

    private GRect paddle; /* X-coord controlled by mouse, Y-coord is fixed */

    private GOval ball;

    private double vx; /* change in x-direction in pixels */

    private double vy = 3.0; /* change in y-direction in pixels, set at 3 */

    private RandomGenerator rgen = RandomGenerator.getInstance(); /* to generate a random vx with each new ball, so the game has variety */

    private int brick_counter = 0; /* counts number of bricks removed, in order to track when all bricks are gone */

    private int lives = NTURNS; /* tracks number of 'lives' remaining; starts with constant NTURNS */

    private GLabel win; /* label shown when game is won */

    private GLabel lost; /* label shown when game is lost */
    }

  2. #2
    totj is offline Member
    Join Date
    Mar 2011
    Posts
    13
    Rep Power
    0

    Default

    hello :)

    code is more easily read in wrapped in code tags - [code ] [ /code]
    create a rectangle around the ball and paddle, and then use the rectangles .intersects method to check collision

    http://download.oracle.com/javase/1.5.0/docs/api/java/awt/Rectangle.html

Similar Threads

  1. A beginner's question on String matching
    By nassar in forum New To Java
    Replies: 28
    Last Post: 05-23-2010, 03:44 PM
  2. Java course work beginner's leve,Help
    By ccie007 in forum New To Java
    Replies: 7
    Last Post: 05-17-2010, 06:14 PM
  3. Breakout Game code help.
    By Ceasar in forum New To Java
    Replies: 6
    Last Post: 10-10-2009, 02:30 AM
  4. Help: No code assist for "new" in Scrapbook
    By LouArnold in forum Eclipse
    Replies: 0
    Last Post: 07-17-2009, 05:43 AM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •