Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Beginner Java Question - "Breakout" game. What's my next step?

Tags:

java

This is my first post on SO!

I've on my own been working a few weeks through Stanford's "Programming Methodology" class which is an intro to programming with java. I've been doing all the programs so far with little difficulty, researching what I needed with minimal difficulty.

Right now, all I have are a set of bricks, and a ball that I was able to get to bounce off the walls. Currently the ball doesn't do anything but bounce around in the canvas and just passes through the bricks.
There are lots of steps involved, the other ones I am pretty sure I can take care of. The ones I am having a hard time with are...

1) Get the ball to bounce off the bricks.
2) Get the bricks to disappear when the ball bounces off them.

some resources I've been using -
Using the ACM Graphics Package
Stanford PDF with the assignment guidelines

I guess my question is. What do I need to understand in order to be able to solve the problems I listed above. In one of the lectures, the professor talks about using "getElementAt()" But I don't really understand how that method works or how I can use it to get my ball to bounce off the bricks and then after, make them disappear.

Code I wrote so far -

/*
 * File: Breakout.java
 * -------------------
 * Name: Sandi
 * Section Leader: I'm learning this online
 *
 * 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;

    /* Method: run() */
    /** Runs the Breakout program. */

    public void run() {
        addBricks();
        addBall();

        //velocity of the ball's x and y
        ballVX = 1;
        ballVY = 2;

        while (true) {
            moveBall();
            pause(10);
        }
    }

    private void addBricks() {
        int startY = BRICK_Y_OFFSET;
        GRect brick;

        for (int i = 0; i < NBRICK_ROWS; i++) {

            int startX = BRICK_SEP;

            for (int j = 0; j < NBRICKS_PER_ROW; j++) {
                brick = new GRect(startX, startY, BRICK_WIDTH, BRICK_HEIGHT);
                add(brick);

                colorBricks(brick, Color.RED, 0, 1);
                colorBricks(brick, Color.ORANGE, 2, 3);
                colorBricks(brick, Color.YELLOW, 4, 5);
                colorBricks(brick, Color.GREEN, 6, 7);
                colorBricks(brick, Color.CYAN, 8, 9);

                startX += BRICK_WIDTH + BRICK_SEP;
            }

            startY += BRICK_HEIGHT + BRICK_SEP;
        }
    }

    private void colorBricks(GRect brick, Color color, int fromRowNumber,
            int toRowNumber) {
        //this will make it so that if the bricks are between two y coordinates
        //then the method will set it to a certain color and color it.
        if (brick.getY() >= BRICK_Y_OFFSET + fromRowNumber
                * (BRICK_HEIGHT + BRICK_SEP)
                && brick.getY() <= BRICK_Y_OFFSET + toRowNumber
                        * (BRICK_HEIGHT + BRICK_SEP)) {
            brick.setColor(color);
            brick.setFilled(true);
        }
    }

    private void addBall() {
        ball = new GOval(getWidth() / 2, getHeight() / 2, BALL_RADIUS,
                BALL_RADIUS);
        ball.setFilled(true);
        add(ball);
    }

    private void moveBall() {
        double borderX = ball.getX();
        double borderY = ball.getY();

        if (borderX == 0 || borderX == getWidth() - BALL_RADIUS) {
            ballVX = -ballVX;
        }
        if (borderY == 0 || borderY == getHeight() - BALL_RADIUS) {
            ballVY = -ballVY;
        }

        ball.move(ballVX, ballVY);
    }

    private GOval ball;
    private double ballVX;
    private double ballVY;
}

Thanks guys!

like image 302
Sandi Avatar asked Mar 21 '11 17:03

Sandi


1 Answers

There are of course many things that could be done to enhance your program. But to solve your next problem I think you have to understand a little bit of the "magic" of the classes you are depend on.

I havn't studied your API in depth, but it looks like your call add(brick); adds your brick to an array/collection internally stored in GraphicsProgram (if you can get the source code of the classes you depend on it might be helpfull to read and understand the code). You can access the objects you have added later on with getElementAt. So if you add a brick at the location (10,20) and later call getElementAt(10,20) it should return this brick.

You should modify your moveBall method to check if the new position of the ball would contain a brick and, if so, act accordingly. Something like this:

private void moveBall() {
    double borderX = ball.getX();
    double borderY = ball.getY();

    GRect brick = getElementAt(borderX, borderY);
    if (brick != null) {
        doSomethingWithBall();
    } else {
        if (borderX == 0 || borderX == getWidth() - BALL_RADIUS) {
            ballVX = -ballVX;
        }
        if (borderY == 0 || borderY == getHeight() - BALL_RADIUS) {
            ballVY = -ballVY;
        }
    }

    ball.move(ballVX, ballVY);
}

You might have to fiddle a little bit with the values you pass into getElementAt and what exactly you do when you find a brick. You have to take into account that the bricks are not points but have a height and a width, the ball is moving and not a point, too ...

Edit: Your ball is added to the collection, too. So it might be possible that the ball is returned instead of a brick. You should not pass the actual position of your ball to the getElementAt method but an value where the ball is after it moves half the ball radius when there is no brick in the way.

like image 90
Arne Deutsch Avatar answered Sep 26 '22 02:09

Arne Deutsch