In this lab you are going to
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.
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)
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
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.
#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; }