_THEATRIX: A C++ GAMES CLASS LIBRARY_ by Al Stevens Listing One // ------- skater.cpp #include const int sidesteps = 25; // number of steps in lateral movement const int fwdsteps = 12; // number of steps in front/rear movement const int sstepincr = 5; // lateral x coordinate increments const int fstepincr = 3; // front/rear y coordinate increments // ------- a moving sprite class Skater : public Player { short int steps; // number of steps taken current segment short int mode; // 1-8 = skating pattern #; 11-13 = splash friend class Pond; void OnEnter(int); protected: DECLARE_CUELIST public: Skater(); virtual ~Skater() { } void update_position(); }; // ---- event message map for Skater class CUELIST(Skater) KEYSTROKE('\r', OnEnter) ENDCUELIST // ---- construct a moving sprite Skater::Skater() : Player("skater.gfx", "skater.sfx") { setxy(90,145); // initial position on pond set_imageno(1); // first skater frame appear(); steps = 0; mode = 1; } // --- skater frame animation entry point (once every tick) void Skater::update_position() { switch (mode) { case 1: case 3: case 5: case 7: // --- side to side movement if (++steps == sidesteps) { steps = 0; set_imageno(++mode); break; } if (mode & 2) // modes 3 and 7: to the left setx(getx() - sstepincr); else // modes 1 and 5: to the right setx(getx() + sstepincr); break; case 2: case 4: case 6: case 8: // --- front or back movement if (++steps == fwdsteps) { steps = 0; if (mode == 8) mode = 0; set_imageno(++mode); break; } if (mode < 6) // modes 2 and 4: away from the screen sety(gety() - fstepincr); else // modes 6 and 8: toward the screen sety(gety() + fstepincr); break; case 9: setinterval(3); // slow down refresh rate set_imageno(13); // 1st frame of ice-breaking splash mode++; play_sound_clip(1); break; case 10: set_imageno(12); // 2nd frame of ice-breaking splash mode++; break; case 11: set_imageno(13); // 3rd frame of ice-breaking splash mode++; break; case 12: set_imageno(11); // hole in ice mode++; steps = 0; break; default: if (steps++ == 30) stop_director(); break; } } // ---- pressed Enter, break the ice void Skater::OnEnter(int) { if (mode < 9) { int yp = 35; if (mode == 3 || mode == 7) yp = 25; else if (mode > 3 && mode < 7) yp = 15; setxy(getx()-10, gety() + yp); mode = 9; } } // ---- stationary sprites class Stander : public Player { public: Stander() : Player("skater.gfx") { } }; // ---- the scene: a skating pond class Pond : public SceneDirector { Stander *stander1; Stander *stander2; Skater *skater; void on_timer(); public: Pond(); ~Pond(); }; // ---- construct the scene Pond::Pond() : SceneDirector("pond.pcx") { // --- most distant stationary sprite stander1 = new Stander; stander1->set_imageno(10); stander1->setxy(180,100); stander1->appear(); // --- closest stationary sprite stander2 = new Stander; stander2->set_imageno(9); stander2->setxy(140,130); stander2->appear(); // --- moving sprite skater = new Skater; } Pond::~Pond() { delete skater; delete stander2; delete stander1; } // ---- called after each timer tick void Pond::on_timer() { SceneDirector::on_timer(); if (skater->steps == 0) { switch (skater->mode) { case 1: // -- front lateral segment // set moving sprite in front of others MoveZToFront(skater); break; case 3: case 7: // -- center lateral segment // set moving sprite between other two ChangeZOrder(skater,stander2); break; case 5: // -- rear lateral segment // set moving sprite behind others ChangeZOrder(skater,stander1); break; default: break; } } } int main(int argc,char *argv[]) { process_cmdline(argc,argv); Pond *pond = new Pond; // scene director begin("Pond"); // launch scene delete pond; return 0; }