Results 1 to 10 of 10
Thread: Need help with Breakout game
- 07-06-2009, 06:41 PM #1
Member
- Join Date
- Jul 2009
- Posts
- 21
- Rep Power
- 0
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:
Thanks,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(); }
Tadhg.
-
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?
- 07-07-2009, 02:09 PM #3
Member
- Join Date
- Jul 2009
- Posts
- 21
- Rep Power
- 0
I create the bricks before the game begins like this:
This draws the rows and columns of bricks for me. Then I check is the ball colliding with the bricks 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); } }
and checkObjectCollisions() is this:Java Code:collider = checkObjectCollisions(); if(collider == paddle){ vy = -vy; } if(collider == brick){ vy = -vy; //add code here to remove bricks and increment score }
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.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()); }
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.
- 07-07-2009, 04:59 PM #4
Senior Member
- Join Date
- Mar 2009
- Posts
- 552
- Rep Power
- 5
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!
- 07-07-2009, 09:45 PM #5
this is just a hunch, but here variable brick is set to the last brick created:
and here, you are check if collider == brick, which is 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); }
what you need is a loop to check ALL the bricks.Java Code:if(collider == brick){ vy = -vy; //add code here to remove bricks and increment score }USE CODE TAGS--> [CODE]...[/CODE]
Get NotePad++ (free)
- 07-08-2009, 12:02 PM #6
Member
- Join Date
- Jul 2009
- Posts
- 21
- Rep Power
- 0
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
- 07-09-2009, 06:26 AM #7
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.Java Code:add(brick, brickXCoor, brickDistFromTop);
USE CODE TAGS--> [CODE]...[/CODE]
Get NotePad++ (free)
- 07-09-2009, 01:48 PM #8
Member
- Join Date
- Jul 2009
- Posts
- 6
- Rep Power
- 0
this is stupid, i want to ask a question but my post count has to be 5
- 07-10-2009, 06:35 PM #9
Member
- Join Date
- Jul 2009
- Posts
- 21
- Rep Power
- 0
Ok, I've fixed it:)
Thanks very much for all the help.
- 03-22-2010, 05:26 AM #10
Member
- Join Date
- Mar 2010
- Posts
- 1
- Rep Power
- 0
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
-
Implementing "Game Over" in Minesweeper game based on Gridworld framework.
By JFlash in forum New To JavaReplies: 2Last Post: 08-05-2010, 04:49 AM -
Help with my game!
By Manikyr in forum New To JavaReplies: 6Last Post: 06-06-2009, 11:09 AM -
Game 21
By aRTx in forum Advanced JavaReplies: 3Last Post: 04-04-2009, 12:33 AM -
2D strategy game or 2D war game
By led1433 in forum Java 2DReplies: 5Last Post: 02-10-2009, 06:00 AM -
game
By amith in forum AWT / SwingReplies: 0Last Post: 05-19-2008, 05:16 PM


LinkBack URL
About LinkBacks
Reply With Quote

Bookmarks