# LAB 2 -- BOUNCING BALLS

In this lab you are going to

• design a C++ class
• work with an array of objects of that class
The purpose of this lab is to convince you that programming with C++ classes is allows a more natural way of thinking about the problem.

You are given the "flat" code that draws a ball bouncing off the walls of a rectangle (you can think of it as ball on the a rectangular pool table without holes and friction). The ball rolls and reflects off the walls without losing speed, so that it never stops. Our eventual goal is to program multiple colored balls that are reflected off the walls of the rectangular table and other obstacles that may be on the table, including other balls (you can thing of this as programming the engine of a pinball game with several balls). In this lab we restrict ourselves to a fixed rectangular field without obstacles, and, for simplicity, we let the balls pass through each other.

## Discussion

We need to keep, in some integer variables, the borders (walls), and, for each ball, the current coordinates and the direction of movement (actually, the horizontal and vertical velocities).

We will draw the balls, compute the next position (coordinates) of each ball based on its coordinates and velocity components, update the positions and re-draw after a suitable delay (so that things don't happen in a blur). Additionally, if the computed next position of a ball intersects with a wall, we'll modify the direction of the ball's movement by changing its horizontal and/or vertical velocities to its opposite. The "flat" give-away code shows how this can be done for a single ball. You must read, understand, and play with this simple code. For example, you may do the following simple exercises (you need not submit your solutions)

1. re-position the walls (very easy)
2. make the ball go twice as fast, but don't change the delay.
3. make the ball bounce vertically between the top and the bottom
4. walls (as if dropped from some hight)
5. make the ball slow down a bit after each reflection, until it stops

Of course, we can keep the coordinates and velocities as arrays of integers with tell-tale names, indexed by the number of the ball, then repeating the logic of a single time slice in a loop over all balls. This is likely to result in a program that is hard to read and still harder to extend. Instead, we are going to create a class called Ball which contains the coordinates and velocities of a single ball, and methods for

• detecting the collision with a wall on the next move,
• modifying velocity to simulate a reflection of a wall
• computing the next position and re-drawing the ball.
Then we will create only one array, that of our Ball objects. The main loop of our simulation will be over the objects in this array. For each one, we will
• check if the next position is a collision
• if so, reflect the ball of the wall with which it is going to collide (i.e. change either the horizontal or the vertical velocity component to its opposite)
• perform the move (erase, draw, delay)
So far, we restrict ourselves to the four fixed border walls. The Ball's member function that checks for collisions takes no arguments, and the wall positions are global variables. When we enhance the program later, walls and obstacles on the field will be objects too, and this function will be called for each obstacle, and will take as argument the object representing that obstacle, and similarly for the reflection function).

The simulation driver code will then be as follows:

```    Ball b[NUM_BALLS]; // assuming that the default constructor
// creates different random balls. It will
// be called NUM_BALLS times here.

for(int t=0; t < MAX_TIME; t++){  // time loop
for( int j=0; j < NUM_BALLS; j++ ){
if( b[j].Collides() )
b[j].Reflect();      // reflect only if there is a collision
b[j].Move();
}
Delay(20);
}
```
From this code, design the Ball class that contains the ball's coordinates x, y, the ball's velocity components vx, vy, and methods as used above (the Collides() method returns a bool, true if the next move leads to collision and false otherwise). All drawing occurs in the method Move(). I recommend that the method Reflect() changes only velocity components, not the coordinates of a ball, and is really short.

Task 1: Write the class Ball that works with the above driver code. You can add other methods to your class (such as those for drawing and erasing the ball). Make you balls have varied random velocities and colors.

## Give-away code for a single ball

```#include "SWindows.h"
#include "Graphics.h"
#include "Delay.h"
#include "Mouse.h"

//On a PC, uncomment these and comment out the includes above
//#include "ct_windows.h"
//#include "ct_graphics.h"
//#include "ct_mouse.h"
//#include "ct_delay.h"

#include

#include "IOTools.h"
#include "MathUtil.h"
#include "Random.h"    // for RandomLong(..)

// Borders are global constants
const int  TOP_BORDER    = 50;
const int  BOTTOM_BORDER = 350;
const int  LEFT_BORDER   = 20;
const int  RIGHT_BORDER  = 380;

int main(){

BigSquarePair();
SetRandomSeed();   // set current time as the random seed

// set and draw the border walls
SetForeColor( 255, 0, 0 );
FrameRect( LEFT_BORDER, TOP_BORDER, RIGHT_BORDER, BOTTOM_BORDER );

// variables describing the ball:

int x = 200;   // x-coordinate
int y = 200;   // y-coordinate
int vx = 5;  // velocity along the x-axis
int vy = -5;  // velocity along the y-axis

for(int t=0; t<1000; t++){  // time
// comupute the new position
int new_x = x + vx;
int new_y = y + vy;

// Check if the ball is at the boundary and reflect it if so.
//
// The ball is contained in the rectangle with the corners
//
// If either of these four points lies on the border or beyond,
// the ball will collide with the border on the next move

if( new_x - rad <= LEFT_BORDER  ||  new_x + rad >= RIGHT_BORDER )
vx = -vx;  // change the direction along the x-axis

if( new_y - rad <= TOP_BORDER   ||  new_y + rad >= BOTTOM_BORDER )
vy = -vy;  // change the direction along the y-axis

SetForeColor( 255, 255, 255 );  // white
PaintCircle( x, y, rad );       // erase the ball

x += vx;      // update the coords of the ball
y += vy;

SetForeColor( 0, 0, 255 );      // blue