// File: game.cxx // Plays an interactive snake game #include #include #include using namespace std; // When steve gets this much money, the big gnat always moves toward him! const int FULL = 28; const int MANY_GNATS = 30; class sprite { public: // The first sprite constructor sets it to a small black circle; // The second sprite constructor sets the properties to specfied // values; both set the sprite to a random location. sprite( ); sprite(int c, int r, char s); // The following member functions can change the properties // or location of a sprite: void set_properties(int c, int r, char s); void set_location(double x, double y); void set_random_location( ); void relative_move(double delta_x, double delta_y); void move_randomly( ); void move_toward (double target_x, double target_y, double amount); void move_toward(sprite target, double amount); void move_toward_mouse(double amount); // These functions don't change a sprite, but they give some // information or do some output with the sprite: bool has_hit(sprite other) const; bool has_hit(sprite others[], int n) const; void draw( ) const; sprite operator *(double multiplier) const; void operator ++( ); private: // This is the information that every sprite contains: int color; int radius; char shape; // 'C' for circle or 'S' square double x; double y; }; sprite sprite::operator *(double multiplier) const { sprite answer(color, int(multiplier*radius), shape); return answer; } void sprite::operator ++( ) { radius++; } sprite::sprite( ) { set_properties(1 + rand() % 15, 2, 'C'); set_random_location( ); } sprite::sprite(int c, int r, char s) { set_properties(c, r, s); set_random_location( ); } void sprite::set_properties(int c, int r, char s) { color = c; radius = r; shape = s; } bool sprite::has_hit(sprite other) const { double distance, delta_x, delta_y; delta_x = x - other.x; delta_y = y - other.y; distance = sqrt(delta_x*delta_x + delta_y*delta_y); return (distance < (radius + other.radius)); } bool sprite::has_hit(sprite others[], int n) const { int i; for (i = 0; i < n; ++i) { if (has_hit(others[i])) return true; } return false; } void sprite::relative_move(double delta_x, double delta_y) { set_location(x+delta_x, y+delta_y); } void sprite::move_randomly( ) { move_toward(x+ (rand() % 3) - 1, y+ (rand()%3) - 1, 1); } void sprite::move_toward (double target_x, double target_y, double amount) { double d_x = target_x - x; double d_y = target_y - y; double d = sqrt(d_x*d_x + d_y*d_y); if (d > amount) relative_move((d_x/d)*amount, (d_y/d)*amount); else set_location(target_x, target_y); } void sprite::move_toward(sprite target, double amount) { move_toward(target.x, target.y, amount); } void sprite::move_toward_mouse(double amount) { move_toward(mousex(), mousey(), amount); } void sprite::set_location(double x, double y) { this->x = x; this->y = y; } void sprite::set_random_location( ) { set_location(rand( ) % (getmaxx( )+1), rand( ) % (getmaxy( )+1)); } void sprite::draw( ) const { setfillstyle(SOLID_FILL, color); switch (shape) { case 'C': fillellipse((int)x, (int)y, radius, radius); break; case 'S': bar((int)x-radius, (int)y-radius, (int)x+radius, (int)y+radius); break; } } int main( ) { // Initialize the graphics and random numbers: srand(time(NULL)); initwindow(300, 300, "Steve vs the Gnats!", 0, 0, true); // Variable declarations and big gnat initialization: int i; int stash = 0; sprite steve(YELLOW, 5, 'S'); sprite money (GREEN, 5, 'C'); sprite door(MAGENTA, 7, 'S'); sprite gnats[MANY_GNATS]; gnats[0].set_properties(RED, 15, 'C'); gnats[1] = gnats[0]*0.1; while (!steve.has_hit(gnats, MANY_GNATS) && !steve.has_hit(door)) { // Mess around with the sprites: steve.move_toward_mouse(2.5); if (steve.has_hit(money)) { stash++; money.set_random_location( ); ++gnats[0]; } if (rand( ) % FULL < stash) gnats[0].move_toward(steve, 2.5); for (i = 0; i < MANY_GNATS; i++) gnats[i].move_randomly( ); // Draw the sprites and the money bar: clearviewport( ); steve.draw( ); money.draw( ); door.draw( ); for (i = 0; i < MANY_GNATS; i++) gnats[i].draw( ); setfillstyle(SOLID_FILL, GREEN); bar(0, getmaxy()-10, stash*getmaxx()/FULL, getmaxy( )); swapbuffers( ); // Sleep for a bit: delay(100); } // Print a message and wait for a key press: if (steve.has_hit(door)) bgiout << "Steve escaped with $" << stash << "!"; else bgiout << "Steve got et!"; outstreamxy(10, 10); getch( ); return 0; }