// File: lunar.cxx // Written by Michael Main, Sep 15, 2005 // This is a demonstration game. The user tries to land a lunar lander. #include // Provides bgi graphics #include // Provides cout using namespace std; /////////////////////////////////////////////////////////////////////////////// // Physical constants const double FORCE_MAIN_THRUSTER = 3000; // kg m/s^2 const double FORCE_SIDE_THRUSTER = 30; // kg m/s^2 const double GRAVITY = -9.8/6; // m/s^2 const double MASS_LANDER = 1000; // kg const double STARTING_FUEL = 250; // kg const int DELAY = 10; // ms const double DELTA_T = DELAY/1000.0; // s // Graphical constants const double IMAGE_SIZE = 0.65; const int WINDOW_WIDTH = static_cast(851*IMAGE_SIZE); const int WINDOW_HEIGHT = static_cast(608*IMAGE_SIZE); const int GROUND_ZERO_Y = static_cast(566*IMAGE_SIZE); const int ROCKET_SIZE = static_cast(100*IMAGE_SIZE); const double PIXELS_PER_METER = 10; const int BACKGROUND_BYTES = 2069656; const int ROCKET_BYTES = 68896; /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // Function prototypes (in alphabetical order) // Draw the background image void draw_background( ); // Draw the lander on the screen. void draw_lander( double x, double y, // Current x and y positions (m) double r, // Current rotational pos (radians) bool main, bool left, bool right // Which thrusters are on ); // Write some of the state data to the screen void draw_stats( double vx, double vy, // Current velocities (m/s) double vr, // Current rotational velocitie (radians/s) double fuel, // Remaining fuel (kg) double t // Current time (s) ); /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// //The main program int main( ) { bool main = false, left = false, right = false; // Are the thrusters on? double x = (static_cast(WINDOW_WIDTH)/PIXELS_PER_METER)/2.0; double y = (static_cast(GROUND_ZERO_Y)/PIXELS_PER_METER); double fuel; // Remaining fuel (kg) double vx, vy; // Velocity (m/s) double r; // Rotational pos radians double vr; // Rotational radians/sec double t = 0; // Time since start initwindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Mario", 0, 0, true); do { // Adjust the control variables: main, left, and right // Adjust the physical variables: positions, velocities, fuel, t t += DELTA_T; // Redraw the screen and delay draw_background( ); draw_lander(x,y,r,main,left,right); draw_stats(vx,vy,vr,fuel,t); swapbuffers( ); delay(DELAY); } while(true); return 0; } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// void draw_background( ) { static bool first = true; static char buffer[BACKGROUND_BYTES]; if (first) { readimagefile("bg.bmp", 0, 0, WINDOW_WIDTH-1, WINDOW_HEIGHT-1); getimage(0, 0, WINDOW_WIDTH-1, WINDOW_HEIGHT-1, buffer); first = false; } else { putimage(0, 0, buffer, COPY_PUT); } } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// void draw_lander( double x, double y, // Current x and y positions (m) double r, // Current rotational pos (radians) bool main, bool left, bool right // Which thrusters are on ) { static bool first = true; static char buffer[8][ROCKET_BYTES]; if (first) { // Make and store all the different rocket images: readimagefile("rocket0.bmp", 0, 0, ROCKET_SIZE-1, ROCKET_SIZE-1); getimage(0, 0, ROCKET_SIZE-1, ROCKET_SIZE-1, buffer[0]); readimagefile("rocket1.bmp", 0, 0, ROCKET_SIZE-1, ROCKET_SIZE-1); getimage(0, 0, ROCKET_SIZE-1, ROCKET_SIZE-1, buffer[1]); readimagefile("rocket2.bmp", 0, 0, ROCKET_SIZE-1, ROCKET_SIZE-1); getimage(0, 0, ROCKET_SIZE-1, ROCKET_SIZE-1, buffer[2]); readimagefile("rocket3.bmp", 0, 0, ROCKET_SIZE-1, ROCKET_SIZE-1); getimage(0, 0, ROCKET_SIZE-1, ROCKET_SIZE-1, buffer[3]); readimagefile("rocket4.bmp", 0, 0, ROCKET_SIZE-1, ROCKET_SIZE-1); getimage(0, 0, ROCKET_SIZE-1, ROCKET_SIZE-1, buffer[4]); readimagefile("rocket5.bmp", 0, 0, ROCKET_SIZE-1, ROCKET_SIZE-1); getimage(0, 0, ROCKET_SIZE-1, ROCKET_SIZE-1, buffer[5]); readimagefile("rocket6.bmp", 0, 0, ROCKET_SIZE-1, ROCKET_SIZE-1); getimage(0, 0, ROCKET_SIZE-1, ROCKET_SIZE-1, buffer[6]); readimagefile("rocket7.bmp", 0, 0, ROCKET_SIZE-1, ROCKET_SIZE-1); getimage(0, 0, ROCKET_SIZE-1, ROCKET_SIZE-1, buffer[7]); first = false; } // Get the right rocket image and put it on the screen: putimage( static_cast(x*PIXELS_PER_METER), static_cast(GROUND_ZERO_Y - y*PIXELS_PER_METER), buffer[3], OR_PUT ); } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// void draw_stats( double vx, double vy, // Current velocities (m/s) double vr, // Current rotational velocitie (radians/s) double fuel, // Remaining fuel (kg) double t // Current time (s) ) { bgiout << "Horizontal velocity (m/s): " << vx << endl; bgiout << "Vertical velocity (m/s): " << vy << endl; bgiout << "Rotational velocity (radians/sec): " << vr << endl; bgiout << "Remaining fuel (kg): " << fuel << endl; bgiout << static_cast(t) << endl; outstreamxy(10, 10); } ///////////////////////////////////////////////////////////////////////////////