Results 1 to 10 of 10
  1. #1
    tfitz666 is offline Member
    Join Date
    Jul 2009
    Posts
    21
    Rep Power
    0

    Default Need help with Breakout game

    Hi,
    I'm doing the Stanford Engineering Everywhere CS106a course. We've have been given an assignment to make the Breakout game. My problem is getting the ball to bounce off the bricks, I can get it to bounce off the paddle and walls alright but it will only detect a collision and bounce off the last brick created(the one in the bottom right corner). Any help(or even unrelated comments on my coding style) would be greatly appreciated. Here's my code:
    Java Code:
    /*
     * File: Breakout.java
     * -------------------
     * Name:
     * Section Leader:
     * 
     * 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;
    	
    /* The horizontal and vertical centres of the window */
    	private static final int CENTRE_WINDOW_HOR = WIDTH/2;
    	private static final int CENTRE_WINDOW_VER = HEIGHT/2;
    	
    /** Runs the Breakout program. */
    	public void run() {
    		addMouseListeners();
    		setupGame();
    		runGame();
    	}
    	
    	private void setupGame(){
    			drawBricks(BRICK_SEP, NBRICKS_PER_ROW, NBRICK_ROWS, BRICK_WIDTH, BRICK_HEIGHT, BRICK_Y_OFFSET);
    			addPaddle(PADDLE_WIDTH, PADDLE_Y_OFFSET);
    	}
    	
    	private void runGame(){
    		
    		while(lives > 0){
    			addBall();
    			vx = getRandomXVector();
    			pause(2000); //todo: make a method that does a 3-2-1 countdown before relaunching the ball.
    			boolean dead = false;
    			while(!dead){
    				moveBall();
    				vx = checkVerticalCollision(vx);
    				vy = checkTopCollision(vy);
    				dead = checkBottomCollision();
    				collider = checkObjectCollisions();
    				if(collider == paddle){
    					vy = -vy;
    				}
    				if(collider == brick){
    					vy = -vy;
    					//add code here to remove bricks and increment score
    				}
    					
    				pause(20);
    			}
    			lives--;
    		}
    	}
    	
    /* Moves the paddle along the x-axis with the mouse */	
    	public void mouseMoved(MouseEvent e){
    		paddle.move((e.getX()-paddle.getX()) - PADDLE_WIDTH / 2, 0); 
    		
    		if(paddle.getX() < 0){ // Sets the paddle to the leftmost side of the app window if the cursor leaves the window on the left.
    			paddle.setLocation(0, (HEIGHT - PADDLE_Y_OFFSET));
    		} else if((paddle.getX() + PADDLE_WIDTH) > WIDTH) { // Sets the paddle to the rightmost side of the app window if the cursor leaves the window on the right.
    			paddle.setLocation((WIDTH - PADDLE_WIDTH), (HEIGHT - PADDLE_Y_OFFSET));
    		}
    	}
    	
    /*Moves the ball using a random X vector and predefined Y vector*/
    	private void moveBall(){
    		ball.move(vx, vy);
    	}
    	
    /*Checks for collisions with the programs vertical bounds(i.e. the two sides) and reverses the x vector if there is.*/
    	private double checkVerticalCollision(double xVector){
    		if(((ball.getX() + (BALL_RADIUS * 2)) > WIDTH )|| (ball.getX() < 0)){ 
    			return -xVector; 
    		}
    		return xVector;
    	}
    	
    /*Checks for collisions with the programs top bounding and reverses the value of the y vector if there is.*/
    	private double checkTopCollision(double yVector){
    		if(ball.getY() < 0){
    			return - yVector;
    		} 
    		return yVector;
    	}
    
    /*Checks for collisions with the bottom bounding and returns TRUE if there is.*/
    	private boolean checkBottomCollision(){
    		return ((ball.getY() + BALL_RADIUS * 2) > HEIGHT);
    	}
    	
    /*Checks for collisions with the paddle or bricks and returns which if there is a collision*/
    	private GObject checkObjectCollisions(){
    		return getElementAt(ball.getX(), ball.getY());
    	}
    	
    	
    	private void addPaddle(int paddleWidth, int distFromBottom){
    		paddle.setFilled(true); //Fills black
    		add(paddle, CENTRE_WINDOW_HOR -(PADDLE_WIDTH/2), (HEIGHT - distFromBottom));		
    	}
    	
    	private void addBall(){
    		ball.setFilled(true);
    		add(ball, CENTRE_WINDOW_HOR - BALL_RADIUS, CENTRE_WINDOW_VER - BALL_RADIUS);
    	}
    
    /*Sets up the bricks for the game given the various parimeters */
    	private void drawBricks(int brickSeperation, int bricksPerRow, int brickRows, int brickWidth, int brickHeight, int brickDistFromTop){
    		for(int i = 0; i < brickRows; i++){
    			int brickXCoor = (brickSeperation / 2); //Must be left here as brickXCoor is "reset" after each iteration of the inner for loop.
    			for(int j = 0; j < bricksPerRow; j++){
    				brick = new GRect(brickWidth, brickHeight);
    				brick.setFilled(true);
    				brick.setColor(chooseBrickColor(i));
    				add(brick, brickXCoor, brickDistFromTop);
    				brickXCoor += (brickWidth + brickSeperation);
    			}
    			brickDistFromTop += (brickHeight + brickSeperation);		
    		}
    	}
    
    	
    /*Creates a pseudo-random X vector for the ball between -3&-1 and 1&3*/	
    	private double getRandomXVector(){
    		vx = rgen.nextDouble(1.0, 3.0);
    		if(rgen.nextBoolean()) vx = -vx;
    		return vx;
    	}
    	
    	
    /* 	Chooses the color of the brick based on what row it is in. If the brick is on the 8th row(rowNumber == 7) or past its colour will be cyan.*/
    	private Color chooseBrickColor(int rowNumber){
    		if(rowNumber == 0 || rowNumber == 1){
    			return Color.RED;			
    		} else if(rowNumber == 2 || rowNumber == 3){
    			return Color.ORANGE;
    		} else if(rowNumber == 4 || rowNumber == 5){
    			return Color.YELLOW;
    		} else if(rowNumber == 6 || rowNumber == 7){
    			return Color.GREEN;
    		} else {
    			return Color.CYAN;
    		}	
    	}
    	
    /* Creates the paddle*/
    	private GRect paddle = new GRect(PADDLE_WIDTH, PADDLE_HEIGHT);
    
    /* Creates the ball*/
    	private GOval ball = new GOval(BALL_RADIUS*2, BALL_RADIUS*2);
    
    /* X & Y vectors used for the ball. */
    	private double vx;
    	private double vy = 3.0;	
    	
    /*Numbers of lives the player has left*/
    	private int lives = NTURNS;
    	
    	private GObject collider; 
    	
    	private GRect brick;
    
    	private RandomGenerator rgen = new RandomGenerator();
    
    }
    Thanks,
    Tadhg.

  2. #2
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    25

    Default

    Time to do some debugging, my friend.

    It's not clear to me where you're checking for collisions between the ball and the bricks. Do you create a collection of Bricks? Do you loop through this looking for collisions?

  3. #3
    tfitz666 is offline Member
    Join Date
    Jul 2009
    Posts
    21
    Rep Power
    0

    Default

    I create the bricks before the game begins like this:
    Java Code:
    /*Sets up the bricks for the game given the various parimeters */
    	private void drawBricks(int brickSeperation, int bricksPerRow, int brickRows, int brickWidth, int brickHeight, int brickDistFromTop){
    		for(int i = 0; i < brickRows; i++){
    			int brickXCoor = (brickSeperation / 2); //Must be left here as brickXCoor is "reset" after each iteration of the inner for loop.
    			for(int j = 0; j < bricksPerRow; j++){
    				brick = new GRect(brickWidth, brickHeight);
    				brick.setFilled(true);
    				brick.setColor(chooseBrickColor(i));
    				add(brick, brickXCoor, brickDistFromTop);
    				brickXCoor += (brickWidth + brickSeperation);
    			}
    			brickDistFromTop += (brickHeight + brickSeperation);		
    		}
    	}
    This draws the rows and columns of bricks for me. Then I check is the ball colliding with the bricks like this:
    Java Code:
    collider = checkObjectCollisions();
    				if(collider == paddle){
    					vy = -vy;
    				}
    				if(collider == brick){
    					vy = -vy;
    					//add code here to remove bricks and increment score
    				}
    and checkObjectCollisions() is this:
    Java Code:
    /*Checks for collisions with the paddle or bricks and returns which if there is a collision*/
    	private GObject checkObjectCollisions(){
    		return getElementAt(ball.getX(), ball.getY());
    	}
    For simplicity I'm assuming that the ball is a single point(the top left corner) for the moment but ill adjust this when I have the basic model working.
    The problem I'm having is that the ball only detects collisions with the last brick created(the one in the bottom row and rightmost column.) So I have a feeling the prob;em is with the way I'm creating the bricks and not the collision detection. Any ideas??
    Thanks again,
    Tadhg.

  4. #4
    Singing Boyo is offline Senior Member
    Join Date
    Mar 2009
    Posts
    552
    Rep Power
    6

    Default

    Hmm... You appear to be using some non-standard classes (GRect, GOval, etc.) but they are documented, and they also having a getBounds() method... Rectangles (which are returned by getBounds()) have an intersects(Rectangle r) method that tests if one rectangle intersects another. Not sure how much this would help, but it is there.
    If the above doesn't make sense to you, ignore it, but remember it - might be useful!
    And if you just randomly taught yourself to program, well... you're just like me!

  5. #5
    angryboy's Avatar
    angryboy is offline Senior Member
    Join Date
    Jan 2009
    Posts
    742
    Rep Power
    6

    Default

    this is just a hunch, but here variable brick is set to the last brick created:
    Java Code:
    for(int j = 0; j < bricksPerRow; j++){
    				brick = new GRect(brickWidth, brickHeight);
    				brick.setFilled(true);
    				brick.setColor(chooseBrickColor(i));
    				add(brick, brickXCoor, brickDistFromTop);
    				brickXCoor += (brickWidth + brickSeperation);
    			}
    and here, you are check if collider == brick, which is the last brick created.
    Java Code:
    if(collider == brick){
    					vy = -vy;
    					//add code here to remove bricks and increment score
    				}
    what you need is a loop to check ALL the bricks.
    USE CODE TAGS--> [CODE]...[/CODE]
    Get NotePad++ (free)

  6. #6
    tfitz666 is offline Member
    Join Date
    Jul 2009
    Posts
    21
    Rep Power
    0

    Default

    Thanks for the replies.
    I kind of guessed that it was something like angryboy said. Sorry for such a newbie question, but how do I fix it(i.e. create a loop to check ALL the bricks)? Do I need to create them with different names brick1, brick2, brick3 etc.?
    Thanks again

  7. #7
    angryboy's Avatar
    angryboy is offline Senior Member
    Join Date
    Jan 2009
    Posts
    742
    Rep Power
    6

    Default

    Java Code:
    add(brick, brickXCoor, brickDistFromTop);
    In the code above, you are adding brick somewhere. Is there also a get method? You will need to get the reference for each brick and check for collision.
    USE CODE TAGS--> [CODE]...[/CODE]
    Get NotePad++ (free)

  8. #8
    stevemilw is offline Member
    Join Date
    Jul 2009
    Posts
    6
    Rep Power
    0

    Default

    this is stupid, i want to ask a question but my post count has to be 5

  9. #9
    tfitz666 is offline Member
    Join Date
    Jul 2009
    Posts
    21
    Rep Power
    0

    Default

    Ok, I've fixed it:)
    Thanks very much for all the help.

  10. #10
    giqcass is offline Member
    Join Date
    Mar 2010
    Posts
    1
    Rep Power
    0

    Default

    It looks like your code could have been checking to see if they were the same object instead of just equal. I'm doing the same problem. It's funny how much different your implementation is even though we broke the problem down in a similar way. My problem was that I did not put the ball as the bottom object on the canvas.

Similar Threads

  1. Replies: 2
    Last Post: 08-05-2010, 04:49 AM
  2. Help with my game!
    By Manikyr in forum New To Java
    Replies: 6
    Last Post: 06-06-2009, 11:09 AM
  3. Game 21
    By aRTx in forum Advanced Java
    Replies: 3
    Last Post: 04-04-2009, 12:33 AM
  4. 2D strategy game or 2D war game
    By led1433 in forum Java 2D
    Replies: 5
    Last Post: 02-10-2009, 06:00 AM
  5. game
    By amith in forum AWT / Swing
    Replies: 0
    Last Post: 05-19-2008, 05:16 PM

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
  •