C481 B581 Computer Graphics
Dana Vrajitoru
C481/B581 Homework 5

Due date: Monday, February 20, 2017.

Ex. 1 In this homework we will continue the Brick Break game by adding a set of bricks that can be broken by bouncing the ball against them.

We will continue with the code from the last week. If you need a solution to any part of it (after you turn it in), let me know.

a. Download the new class GameObject which will serve as base for all our game objects, along with the new definition for Ball and Paddle:

GameObject.h
GameObject.cc
Ball.h
Paddle.h

Note that GameObject defines a couple of attributes for the object being visible and active, as well as its position and color. It declares the functions draw, move, and intersect (with a ball) as virtual, so that they can be called from a pointer to the base class and be linked to the methods of the actual derived class of the referenced object at runtime.

Add the prototypes of whatever class methods you added to Ball and to Paddle in Homework 4 to these new definitions of the classes. Delete the class methods in Ball.cc and Paddle.cc that are inherited from GameObject without change. Note that the functions draw and move need to stay. Add GameObject.o to the Makefile.

Modify the function move in the class Ball such that if the ball falls below the bottom border of the window, the ball becomes inactive and invisible.

b. Add another class called Brick, similar in implementation to the class Paddle, either derived from GameObject or from the class Paddle (whichever you think might work better). The bricks will need a function that checks for collision with the ball, just like the paddle (can you use the same?). Note that for the paddle you can assume that the ball arrives from above, while for the bricks it can arrive from any direction. Add Brick.o to the Makefile.

In the collision function for the brick, if the brick is inactive or invisible, you should simply return false. Otherwise in case of collision with the ball, you need to make the brick both inactive and invisible, then return true.

Ex. 2. Adding an array of bricks.

a. New Globals. At the top of brickbreak.cc, below your definition of the ball and the paddle, add the following:

GameObject **scene;
int nrObjects;
const int ROWS=3, COLS=5;


c. Add the following function to brickbreak.cc:

// create all the scene objects
void createObjects()
{
    nrObjects = ROWS * COLS + 2; // bricks plus ball and paddle
    scene = new GameObjectPtr[nrObjects]; // allocate the memory
    scene[ROWS * COLS] = &theBall; // register the ball in the array
}

Add another instruction to register your Paddle object in this array at position ROWS * COLS + 1. Add here the functionality of creating the 15 bricks and storing their pointers in the array scene from 0 to ROWS * COLS -1. Call this function in myinit just before resetObj.

c. Draw. Replace the function draw with the following code:

// Draws all the objects in the scene
void draw()
{
    glClear(GL_COLOR_BUFFER_BIT);
    for (int i=0; i < nrObjects; i++)
        if (scene[i] && scene[i]->visible) // only draw visible objects
            scene[i]->draw();
    glutSwapBuffers();
}

Remove all other calls to the function draw for the ball or the paddle, wherever they happen.

d. Move. Comment out the function call to glutIdleFunc in initWindowGui and add the following function call:

glutTimerFunc(50, move, 1);

Add the following overloaded function move to brickbreak.cc and the prototype in brickbreak.h:

// Moves all the objects in the scene
void move(int value)
{
    if (value) {
        for (int i=0; i < nrObjects; i++)
            if (scene[i] && scene[i]->active) // only move active objects
                scene[i]->move();
        resolveCollisions(); // detect and resolve collisions
        glutPostRedisplay();
        glutTimerFunc(50, move, !gameOver());
    }
}

e. Collision resolution and game over. Implement the functions in brickbreak.cc for detecting and resolving collisions, and for checking if the game is over, with the following prototypes:

// Checks if the game is over
bool gameOver();

// Detects and resolves all the collisions
void resolveCollisions();

Ex. 3. (3 pts. extra credit) Implement a couple of "reserve" balls available to the player. These objects should be visible but inactive. They should be displayed on the screen somewhere. When a ball is lost, if one of the reserves is still visible, it should be reset to the bottom center of the screen, its speed randomized, and made active. If none of the reserves is still visible, the game is over.

Upload to Canvas: the source file(s) that you modify. You don't need to upload the Makefile.