0
\$\begingroup\$

I want to make Breakout, but I am having problems destroying the bricks upon collision with the ball, all the bricks disappear upon collision, however, I only want the hit brick to disappear, how can I achieve that? (I am using allegro and C++) The Bricks class:-

class Bricks{
public:
int x;
int y;
bool isDestroyed;
ALLEGRO_BITMAP *brick;
}Brickss[40];

The draw function:-

void draw(){
al_draw_bitmap(background, 0, 0, 0);
al_draw_bitmap(paddle, paddleXPos, paddleYPos, 0);
al_draw_bitmap(ball, ballXPos, ballYPos, 0);
for (int drawBricks = 0; drawBricks < 8; drawBricks++){
    for (Brickss[drawBricks].x = 0; Brickss[drawBricks].x < 1000; Brickss[drawBricks].x += 120){
        Brickss[drawBricks].y = 0;

        if (Brickss[drawBricks].isDestroyed == false){
            al_draw_bitmap(Brickss[drawBricks].brick, Brickss[drawBricks].x, Brickss[drawBricks].y, 0);

        }
    }


    }

al_flip_display();

}

The main function:-

int main(){
//initialize all what we need in allegro and load all the pictures(background,ball,paddle,bricks)
init();
loadBitmaps();
while (!done){
    al_clear_to_color(al_map_rgb(255, 255, 0));

    ALLEGRO_EVENT ev;
    al_wait_for_event(eventqueue, &ev);
    al_start_timer(timer);
    //motion of the ball
    if (ev.type == ALLEGRO_EVENT_TIMER){
        moveBall();
    }
    //motion of the player
    if (ev.keyboard.keycode == ALLEGRO_KEY_LEFT){
        paddleXPos -= movePaddleX;
    }
    if (ev.keyboard.keycode == ALLEGRO_KEY_RIGHT){
        paddleXPos += movePaddleX;
    }
    //bounce back if the ball hits the paddle
    if (intersects(ball, paddle, ballXPos, ballYPos, paddleXPos, paddleYPos)){
        moveBallX *= -1;
        moveBallY *= -1;
    }
    for (int drawBricks = 0; drawBricks < 8; drawBricks++){
        for (Brickss[drawBricks].x = 0; Brickss[drawBricks].x < 1000; Brickss[drawBricks].x += 120){
            Brickss[drawBricks].y = 0;


            if (intersects(ball, Brickss[drawBricks].brick, ballXPos, ballYPos, Brickss[drawBricks].x, Brickss[drawBricks].y)){

                Brickss[drawBricks].isDestroyed = true;

            }
        }
    }
        //draw everything to the backbuffer
        al_set_target_backbuffer(display);
        draw();
    }
    al_flip_display();
    al_rest(10);


}
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

The problem is with how you're using your Bricks class. You're using the same Bricks instance to draw multiple bricks (FYI- a more common convention would be for this class to have a singular name: Brick), so when one of those instances is hit, all of the locations that brick is drawn at disappears. Furthermore, the different instances of Bricks are actually all drawn at the same location[s] so when one gets hit, they're all destroyed.

Since your bricks are stationary, consider treating the x and y coordinates as read-only fields, this will prevent you from drawing the same brick in multiple locations.

class Brick 
{
public:
    // Using getter functions prevents these fields from getting changed outside 
    // this class.
    int GetX() { return x; }
    int GetY() { return y; }

    Brick(int x, int y)
    {
        this->x = x;
        this->y = y;
        isDestroyed = false;
        brick = NULL;
    }

    bool isDestroyed;
    ALLEGRO_BITMAP* brick;
private:
    int x, y;
};

When iterating through the bricks, you can just iterate through them. Don't try to change their coordinates like you're currently doing in order to draw them in more places. If you want more bricks, just create more Brick objects.

// Update
for (int i = 0; i < BRICK_COUNT; i++)
{
    if (intersects(ball, Brickss[i].brick, ballXPos, ballYPos, Brickss[i].GetX(), Brickss[i].GetY())
    {
        Brickss[i].isDestroyed = true;
    }
}

// Draw
for (int i = 0; i < BRICK_COUNT; i++)
{
    if (!Brickss[i].isDestroyed)
    {
        al_draw_bitmap(Brickss[i].brick, Brickss[i].GetX(), Brickss[i].GetY(), 0);
    }
}

Edit: To answer your additional question on how to actually initialize your Brick array. There's several ways you can do this in C++. You can search for some tutorials on arrays and pointers, these are not game programming specific concepts, but I'll give a brief overview of two options that will keep the coordinates as read-only.

One. You can set the positions manually when initializing your array.

Brick Bricks[] = { // This can be written after the class declaration as well.
    { 0, 0 }, // This syntax calls the Brick(int x, int y) constructor
    { BRICK_WIDTH, 0 },
    { 0, BRICK_HEIGHT },
    // ....
};

Two. Doing that isn't really the best design and makes it more difficult to do other things like loading the brick layout from a file or randomly generating it. So instead of a array of Brick, you could use an array of pointers to Brick (Brick*). This way you can dynamically create the objects during the level initialization.

Brick* Bricks[BRICK_COUNT];
for (int i = 0; i < BRICK_COUNT; i++)
{
    // You can decide how you want to compute the coordinates.
    Bricks[i] = new Brick((i % BRICKS_PER_ROW) * BRICK_WIDTH, (i / BRICKS_PER_ROW) * BRICK_HEIGHT);
}

// Because these are now Brick*, you can use the -> operator instead of . to access fields:
Bricks[i]->GetX();

// Because you're allocating objects with the new command, remember to delete
// them when you're done with them.
for (int i = 0; i < BRICK_COUNT; i++)
{
    delete Bricks[i];
}
\$\endgroup\$
2
  • \$\begingroup\$ Hello, thank you, but I've been trying to do something similar to what you've demonstrated, but I don't get something, how will their positions be determined if I don't iterate through them and give each one a different position? Also, when I try to change my bricks class to be similar to yours, and add a Brickss[40] object, I get an error that 'no appropriate default constructor available', I am confused, could you please help me? \$\endgroup\$ Jun 8, 2016 at 14:12
  • \$\begingroup\$ @AlbertWilliams I have edited my answer with some tips on constructing your brick array. You may want to look up some tutorials on arrays and pointers in C++ for more information. \$\endgroup\$
    – milk
    Jun 8, 2016 at 20:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .