#include "canvas.h" #include "randgen.h" #include "dice.h" #include "mathutils.h" // illustrates iteration over all canvas objects by a shape/bouncer // The MoleBouncer class bounces, but when a MoleBouncer object collides // with a shape it removes itself and replaces itself by a MoleBouncer // that's BLUE, located in the grid (0..WIDTH/10, 0..HEIGHT/10) of the // canvas it's bouncing in, and travelling in close to the opposite direction // namely 2*PI - angle class MoleBouncer : public Bouncer { public: MoleBouncer(Shape& s, double angle, double v) : Bouncer(s,angle,v) { } Shape * clone() { return new MoleBouncer(*this); } virtual void update(AnimatedCanvas& ac) { RandGen rgen; Iterator it(ac.makeIterator()); bool collided = false; // collision or still bouncing? Point p = getLocation(); double angle = getAngle(); for(it.Init(); it.HasMore(); it.Next()) { // check for collision, but not with myself if (it.Current().id() != this->id() && it.Current().overlaps(*this)) { ac.removeShape(this); ac.addShape( new MoleBouncer(CircleShape(Point(rgen.RandReal(0,ac.width()/10), rgen.RandReal(0,ac.height()/10)), RADIUS, CanvasColor::BLUE), 2*PI - angle, 4)); collided = true; break; } } if (!collided) // no collision, update { Bouncer::update(ac); } } static int RADIUS; // of new molecule/bouncer }; int MoleBouncer::RADIUS = 4; class MakeBouncer : public MKAdapter { public: MakeBouncer() { } void processClick(const Point& p, AnimatedCanvas& ac) { Dice d(6); CircleShape circ(p,d.Roll()*5, CanvasColor::MAGENTA); ac.addShape(new MoleBouncer(circ,2*PI/d.Roll(),d.Roll())); } }; int main() { const int WIDTH=300, HEIGHT=200; AnimatedCanvas ac(WIDTH, HEIGHT, 20,20); MakeBouncer mc; ac.addShape(mc); ac.runUntilEscape(10); return 0; }