/* Bouncing Spheres Program */ #include "animation.C" #include "animation.moc" #include #include /* XBOUND (600), YBOUND (400) */ // Some commonly used colors #define myblack QColor(0,0,0) #define myblue QColor(0,0,255) #define myred QColor(255,0,0) #define mygreen QColor(0,255,0) #define mywhite QColor(255,255,255) int distance(int x1, int y1, int x2, int y2) { return (int) sqrt((double)(((x1-x2)*(x1-x2)) + ((y1-y2)*(y1-y2)))); } int signof(int a) { if (a<0) return -1; else return 1; } //used to test if a, b have opposite signs bool opposite(int a, int b) { return (signof(a) + signof(b)) == 0; } class sphere { private: int x; int y; int radius; // center coords and scale int dx; int dy; // movement vector QColor color; QPainter *brush; // ignore public: sphere(int x0, int y0, int r0, QColor c0, QPainter *b0) { x = x0; y = y0; radius = r0; color = c0; brush = b0; // ignore dx = 0; dy = 0; // sphere initially stationary } void setmovement(int newdx, int newdy) { dx = newdx; dy = newdy; } void move() // change coordinates by dx,dy, bounce off walls { // xbounce if ( (x <= radius) || (x >= (XBOUND-radius)) ) dx = dx * -1; // bounce; if ( (y <= radius) || (y >= (YBOUND-radius)) ) dy = dy * -1; // bounce; x = x + dx; y = y + dy; } // returns true if "this" sphere collided with sphere b bool collided(sphere b) { // have access to x, y and b.x, b.y , radius, b.radius int dist; bool answer; dist = distance(x,y,b.x,b.y); answer = (dist <= radius + b.radius); return answer; } // changes movement after colliding with object moving in direction bdx,bdy void collusion(int bdx, int bdy) { // bounce dx: if ( opposite(dx,bdx) ) dx = dx * -1; else dx = bdx; // bounce dy: if ( opposite(dy,bdy) ) dy = dy * -1; else dy = bdy; } // the next two functions allows read-only access to dx,dy int getdx() { return dx; } int getdy() { return dy; } void draw() // draws figure to double buffer (not directly on screen) { brush->setPen(QPen(color,1)); // set to right color brush->setBrush(QBrush(color)); brush->drawEllipse(x-radius,y-radius,2*radius,2*radius); } }; // end class sphere void mywindow::animate() { int olddx; int olddy; sphere s0(50,100,30,QColor(255,0,0),brush); sphere s1(100,200,20,QColor(0,255,0),brush); s0.setmovement(3,3); s1.setmovement(-2,5); while (true) { s0.draw(); s1.draw(); if (s0.collided(s1)) { olddx = s0.getdx(); // save original values of s0's dx,dy olddy = s0.getdy(); s0.collusion(s1.getdx(), s1.getdy()); s1.collusion(olddx, olddy); } s0.move(); s1.move(); refresh(); // updates screen (new figure will be shown!) delay(50); // 80 millisecond delay before next frame should be shown clear(); // clears screen of old image } }