javaarraysbreakout

Brick positions, in Breakout game, using an array in Java


I have been working on a Java project for Uni, the classic arcade game Breakout, and so far have managed to create the bat and ball objects and they work as intended. I'd like to implement the brick wall using an array as making each brick its own object will result in inefficient code, but my experience with Java doesn't extend to Arrays and I understand, unlike Python, they are tricky to get working.

I'd like the bricks to be given different positions based on x and y parameters already established.

Here is the Model class where I'd like to add the array;

public class Model 
{
    // First, a collection of useful values for calculating sizes and layouts etc.

    public int B              = 6;      // Border round the edge of the panel
    public int M              = 40;     // Height of menu bar space at the top

    public int BALL_SIZE      = 30;     // Ball side
    public int BRICK_WIDTH    = 50;     // Brick size
    public int BRICK_HEIGHT   = 30;

    public int BAT_MOVE       = 5;      // Distance to move bat on each keypress
    public int BALL_MOVE      = 3;      // Units to move the ball on each step

    public int HIT_BRICK      = 50;     // Score for hitting a brick
    public int HIT_BOTTOM     = -200;   // Score (penalty) for hitting the bottom of the screen

    View view;
    Controller controller;

    public GameObj ball;                // The ball
    public ArrayList<GameObj> bricks;   // The bricks
    public GameObj bat;                 // The bat
    public int score = 0;               // The score

    // variables that control the game 
    public boolean gameRunning = true;  // Set false to stop the game
    public boolean fast = false;        // Set true to make the ball go faster

    // initialisation parameters for the model
    public int width;                   // Width of game
    public int height;                  // Height of game

    // CONSTRUCTOR - needs to know how big the window will be
    public Model( int w, int h )
    {
        Debug.trace("Model::<constructor>");  
        width = w; 
        height = h;
    }

    // Initialise the game - reset the score and create the game objects 
    public void initialiseGame()
    {       
        score = 0;
        ball   = new GameObj(width/2, height/2, BALL_SIZE, BALL_SIZE, Color.RED );
        bat    = new GameObj(width/2, height - BRICK_HEIGHT*3/2, BRICK_WIDTH*3, 
            BRICK_HEIGHT/4, Color.GRAY);
        bricks = new ArrayList<>();
        // ***HERE***

    }

And here is the corresponding code I'd like added to View class to draw the bricks in the GUI;

    public void drawPicture()
{
    // the ball movement is runnng 'i the background' so we have
    // add the following line to make sure
    synchronized( Model.class )   // Make thread safe (because the bal
    {
        GraphicsContext gc = canvas.getGraphicsContext2D();

        // clear the canvas to redraw
        gc.setFill( Color.WHITE );
        gc.fillRect( 0, 0, width, height );

        // update score
        infoText.setText("BreakOut: Score = " + score);

        // draw the bat and ball
        displayGameObj( gc, ball );   // Display the Ball
        displayGameObj( gc, bat  );   // Display the Bat

        // ***HERE***

    }
}

The .jar project file in its current state can be viewed here.

On a side note, there is a slight bug with the bat, it does not stop when it hits either side, not sure what's the best way to go about making it stay within the parameters of the window.

Thanks in advance!!


Solution

  • You already have your ArrayList of bricks. Create a function to convert a row/column co-ordinate into an index for your array. Say you have a grid 3x4 (3 rows, 4 columns):

    0 |_|_|B|_|
    1 |_|_|_|_|
    2 |_|_|_|_|
       0 1 2 3
    

    Your ArrayList would be of size 12 (3x4).

    private int translateCoordToIndex(int row, int col) {
      return row * TOTAL_COLS + col
    }
    

    So for the brick at row=0,col=2 in the diagram its position comes out as (0*4)+2 = 2 which means index 2 in your ArrayList bricks.get(2)

    You can even just change the ArrayList into a general array of GameObj GameObj[]

    Alternatively you can use a 2d array of GameObj to represent a grid of bricks.

    GameObj[][] bricks = new GameObj[rows][cols] This way you can access the exact brick using its row and column position - e.g. bricks[0][0] for the first brick.

    Both approaches are pretty much the same.