LAB 2 -- BOUNCING BALLS

In this lab you are going to

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

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 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 
    int rad = 20;  // radius of the ball  

    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
        // (x-rad, y-rad), (x+rad, y+rad), (x-rad, y+rad), (x+rad, y-rad) .  
        // 
        // 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
        PaintCircle( x, y, rad );    

        Delay(20);        // delay so that the animation is not too fast 
    }

    PressReturn();

    return 0;
}