Nemesis game, engine

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Engine.cpp Source File

Engine.cpp

00001 #include "Engine.h"
00002 
00003 #define LEVEL_ONE 2
00004 #define LEVEL_TWO 3
00005 #define LEVEL_THREE 4
00006 #define LEVEL_FOUR 5
00007 #define LEVEL_FIVE 6
00008 
00009 Engine::Engine()
00010 {
00011     collisions = 0;     // Collisions variable. Maximum value of 5.
00012     wave_counter = 0;   // Wave counter variable.
00013     ammo = 3;           // Ammo variable. Shows if rockets (first weapon choice) are available. Maximum value of 3.
00014     star = true;        // Star variable. Shows if a star (second weapon choice) is available.
00015     pauses = 3;         // Pauses variable. Shows how many pauses the player has left.
00016 }
00017 
00018 Engine::~Engine()
00019 {
00020 }
00021 
00022 
00023 // Initialization method:
00024 
00025 void Engine::init(int speed, N5110 &lcd, Gamepad &pad, int _collisions, int _wave_counter, int _ammo, bool _star, int _pauses)
00026 {
00027     _speed = speed;
00028     _friendly.init();       // Friendly ship initialization.
00029     
00030     // Enemy ships initialization:
00031     _enemy1.init(_speed);   
00032     _enemy2.init(_speed);
00033     _enemy3.init(_speed);
00034     _enemy4.init(_speed);
00035     _enemy5.init(_speed);
00036     _enemy6.init(_speed);
00037     printf("%s \n", "Friendly and enemy ships initialized.");
00038     
00039     // Initializing variable values:
00040     collisions = _collisions;         
00041     wave_counter = _wave_counter;
00042     ammo = _ammo;
00043     star = _star;
00044     pauses = _pauses;
00045 }
00046 
00047 
00048 // Method for reading the input from the gamepad analog stick:
00049 
00050 void Engine::read_input(Gamepad &pad)
00051 {
00052     _d = pad.get_direction();
00053     _mag = pad.get_mag();
00054 }
00055 
00056 
00057 // Drawing method:
00058 
00059 void Engine::draw_all(N5110 &lcd)
00060 {
00061     _stats.draw_grid(lcd);                          // Draws initial grid and border.
00062     _stats.draw_health(lcd);                        // Draws health counter (initial state).
00063     _stats.check_health_high(lcd, collisions);      // Checks and draws health counter (later states, high health).
00064     _stats.check_health_low(lcd, collisions);       // Checks and draws health counter (later states, low health).
00065     _stats.check_star(lcd, star);                   // Checks and draws star.
00066     _stats.check_rocket(lcd, ammo);                 // Checks and draws rocket.
00067     _stats.draw_wave_counter(lcd, wave_counter);    // Draws wave counter.
00068     _friendly.draw(lcd);                            // Draws friendly ship.
00069     
00070     // Draws enemy ships:
00071     _enemy1.draw(lcd);                              
00072     _enemy2.draw(lcd);
00073     _enemy3.draw(lcd);
00074     _enemy4.draw(lcd);
00075     _enemy5.draw(lcd);
00076     _enemy6.draw(lcd);
00077 }
00078 
00079 
00080 // Checks for changes in the game:
00081 
00082 void Engine::check_all(N5110 &lcd, Gamepad &pad)
00083 {
00084     check_enemy_pass_high(pad);             // Checks if upper enemy ships passed screen border and generates others.
00085     check_enemy_pass_low(pad);              // Checks if lower enemy ships passed screen border and generates others.
00086     check_friendly_death_all(lcd, pad);     // Checks for collisions and eventual friendly death.
00087     check_health_replenish();               // Checks if health should be replenished.
00088     check_rocket_replenish();               // Checks if rockets should be replenished.
00089     check_star_replenish();                 // Checks if star should be replenished.
00090     check_level_two(lcd, pad);              // Checks if level 2 has been reached.
00091     check_level_three(lcd, pad);            // Checks if level 3 has been reached.
00092     check_level_four(lcd, pad);             // Checks if level 4 has been reached.
00093     check_level_five(lcd, pad);             // Checks if level 5 has been reached.
00094     check_pause(lcd, pad);                  // Checks if the game has been paused/unpaused.
00095     check_mode_toggle(lcd, pad);            // Checks if the LCD mode has been toggled.
00096 }
00097 
00098 
00099 // Dynamic object position/velocity updater:
00100 
00101 void Engine::update_all(N5110 &lcd, Gamepad &pad)
00102 {
00103     _friendly.update_basic(_d,_mag);        // Updates position of friendly ship based on basic horizontal/vertical movements.
00104     _friendly.update_diagonal(_d,_mag);     // Updates position of friendly ship based on diagonal movements.
00105     _friendly.check_pos();                  // Prevents the friendly ship from going off-screen.
00106     
00107     // Updates enemy position:
00108     _enemy1.update();                       
00109     _enemy2.update();
00110     _enemy3.update();
00111     _enemy4.update();
00112     _enemy5.update();
00113     _enemy6.update();
00114 }
00115 
00116 
00117 // Method to enable shooting rockets:
00118 
00119 void Engine::shoot_rocket(N5110 &lcd, Gamepad &pad)
00120 {
00121     Vector2D friendly_pos = _friendly.get_pos();    // Obtains friendly ship's position.
00122     int _x = friendly_pos.x+6;                      // Sets the variables as the nose of the friendly ship.
00123     int _y = friendly_pos.y+3;
00124     _rocket.init(_x, _y);                           // Initializes the rocket at those variables.
00125     
00126     if ((pad.check_event(Gamepad::B_PRESSED) == true) &&    
00127         (ammo > 0))
00128     {   
00129         _rocket.draw(lcd);              // Draws the rocket beam.
00130         check_enemy_death_high(pad);    // Checks for upper enemy ship death.
00131         check_enemy_death_low(pad);     // Checks for lower enemy ship death.
00132         pad.tone(1500.0,0.1);           // Outputs a tone.
00133         ammo = ammo - 1;                // Removes a rocket from the inventory.
00134         printf("A rocket has been shot. Remaining ammo: %d \n", ammo);
00135     }
00136 }
00137 
00138 
00139 // Method to enable shooting rockets:
00140 
00141 void Engine::shoot_star(N5110 &lcd, Gamepad &pad)
00142 {   
00143     if ((pad.check_event(Gamepad::A_PRESSED) == true) &&
00144         (star == true))
00145     {    
00146         // Reinitializes all enemies when a star is shot:
00147         _enemy1.init(_speed);
00148         _enemy2.init(_speed);
00149         _enemy3.init(_speed);
00150         _enemy4.init(_speed);
00151         _enemy5.init(_speed);
00152         _enemy6.init(_speed);
00153         
00154         wave_counter = wave_counter + 1;            // Sends the player to the next wave.
00155         pad.tone(2000.0,0.5);                       
00156         star = false;                               // Removes the star from the inventory.
00157         printf("%s \n", "A star has been shot.");
00158     }
00159 }
00160 
00161 
00162 // Checks if upper enemy ships passed off screen and re-initializes ones that have:
00163 
00164 void Engine::check_enemy_pass_high(Gamepad &pad)
00165 {
00166     Vector2D enemy1_pos = _enemy1.get_pos();
00167     Vector2D enemy2_pos = _enemy2.get_pos();
00168     Vector2D enemy3_pos = _enemy3.get_pos();
00169     
00170     if (enemy1_pos.x < 0) {                 // Checks if the Enemy1 ship's x position is negative (off-screen).
00171         _enemy1.init(_speed);               // Reinitializes Enemy1.
00172         wave_counter = wave_counter + 1;    // Wave counter is associated to Enemy1.
00173         health_regen_trigger = false;       // Sets the regen triggers to false to allow for further regeneration in next waves.
00174         rocket_regen_trigger = false;       
00175         star_regen_trigger = false;
00176         printf("A wave has passed. Current wave: %d \n", wave_counter);
00177     }
00178     if (enemy2_pos.x < 0) {
00179         _enemy2.init(_speed);
00180     }
00181     if (enemy3_pos.x < 0) {
00182         _enemy3.init(_speed);
00183     }
00184 }
00185 
00186 
00187 // Checks if lower enemy ships passed off screen and re-initializes ones that have:
00188 
00189 void Engine::check_enemy_pass_low(Gamepad &pad)
00190 {
00191     Vector2D enemy4_pos = _enemy4.get_pos();
00192     Vector2D enemy5_pos = _enemy5.get_pos();
00193     Vector2D enemy6_pos = _enemy6.get_pos();
00194     
00195     if (enemy4_pos.x < 0) {
00196         _enemy4.init(_speed);
00197     }
00198     
00199     if (enemy5_pos.x < 0) {
00200         _enemy5.init(_speed);
00201     }
00202     
00203     if (enemy6_pos.x < 0) {
00204         _enemy6.init(_speed);
00205     }
00206 }
00207 
00208 
00209 // Checks if upper enemy ships have been destroyed:
00210 
00211 void Engine::check_enemy_death_high(Gamepad &pad)
00212 {
00213     Vector2D friendly_pos = _friendly.get_pos();
00214     
00215     if (friendly_pos.y < 5) {   // Checks if the friendly ship is opposite the Enemy1 ship.
00216         _enemy1.init(_speed);   // Reinitializes the Enemy1 ship.
00217         printf("%s \n", "Enemy1 has been destroyed by a rocket and reinitialized.");
00218     } 
00219     else if ((friendly_pos.y < 11) &&
00220             (friendly_pos.y > 4)) {
00221         _enemy2.init(_speed);
00222         printf("%s \n", "Enemy2 has been destroyed by a rocket and reinitialized.");
00223     }
00224     else if ((friendly_pos.y < 17) &&
00225             (friendly_pos.y > 10)) {
00226         _enemy3.init(_speed);
00227         printf("%s \n", "Enemy3 has been destroyed by a rocket and reinitialized.");
00228     }  
00229 }
00230 
00231 
00232 // Checks if lower enemy ships have been destroyed:
00233 
00234 void Engine::check_enemy_death_low(Gamepad &pad)
00235 {
00236     Vector2D friendly_pos = _friendly.get_pos();
00237     
00238     if ((friendly_pos.y < 25) &&
00239         (friendly_pos.y > 16)) {
00240         _enemy4.init(_speed);
00241         printf("%s \n", "Enemy4 has been destroyed by a rocket and reinitialized.");
00242     }
00243     else if ((friendly_pos.y < 31) &&
00244             (friendly_pos.y > 24)) {
00245         _enemy5.init(_speed);
00246         printf("%s \n", "Enemy5 has been destroyed by a rocket and reinitialized.");
00247     }
00248     else if (friendly_pos.y > 30) {
00249         _enemy6.init(_speed);
00250         printf("%s \n", "Enemy6 has been destroyed by a rocket and reinitialized.");
00251     }    
00252 }
00253 
00254 
00255 // Checks for collisions between friendly and an enemy ship:
00256 
00257 void Engine::check_friendly_death(Gamepad &pad, Vector2D enemy_pos)
00258 {
00259     Vector2D friendly_pos = _friendly.get_pos();
00260     
00261     if ((friendly_pos.y >= enemy_pos.y-5) &&    // Checks if x and y coordinates of friendly and enemy ships
00262         (friendly_pos.y <= enemy_pos.y+5) &&    // match, including the friendly and enemy size.
00263         (friendly_pos.x+6 >= enemy_pos.x) && 
00264         (friendly_pos.x+6 <= enemy_pos.x+5)) 
00265     {
00266         pad.tone(800.0,0.1);
00267         collisions = collisions + 1;            // Registers a collision.
00268     }
00269 }
00270 
00271 
00272 // Checks for collisions between friendly and each enemy ship:
00273 
00274 void Engine::check_friendly_death_all(N5110 &lcd, Gamepad &pad)
00275 {
00276     Vector2D enemy1_pos = _enemy1.get_pos();
00277     Vector2D enemy2_pos = _enemy2.get_pos();
00278     Vector2D enemy3_pos = _enemy3.get_pos();
00279     Vector2D enemy4_pos = _enemy4.get_pos();
00280     Vector2D enemy5_pos = _enemy5.get_pos();
00281     Vector2D enemy6_pos = _enemy6.get_pos();
00282     
00283     // Executes the "check_friendly_death" method for each enemy ship:
00284     check_friendly_death(pad, enemy1_pos);
00285     check_friendly_death(pad, enemy2_pos);
00286     check_friendly_death(pad, enemy3_pos);
00287     check_friendly_death(pad, enemy4_pos);
00288     check_friendly_death(pad, enemy5_pos);
00289     check_friendly_death(pad, enemy6_pos);
00290     
00291     check_gameover(lcd, pad);   // Game over sequence, runs if health subzero.
00292 }
00293 
00294 
00295 // Checks if it is time for health to be replenished:
00296 
00297 void Engine::check_health_replenish()
00298 {
00299     if (!(collisions == 0) &&               // Checks if player isnt already at full health.
00300         (health_regen_trigger == false)) {  // Checks if health hasn't already been replenished this wave. (to prevent spamming)
00301             if ((wave_counter == 20) ||     // Checks if the game is at a certain wave:
00302                 (wave_counter == 40) ||
00303                 (wave_counter == 60) ||
00304                 (wave_counter == 80) ||
00305                 (wave_counter == 100) ||
00306                 (wave_counter == 120) ||
00307                 (wave_counter == 140) ||
00308                 (wave_counter == 160) ||
00309                 (wave_counter == 180) ||
00310                 (wave_counter == 200)) {        
00311             collisions = collisions - 1;    // Adds health to the health bar.
00312             health_regen_trigger = true;    // Sets the trigger to show health has already been replenished this wave.
00313             printf("%s \n", "Health has been regenerated.");
00314             }     
00315     }
00316 }
00317 
00318 
00319 // Checks if it is time for a rocket to be replenished:
00320 
00321 void Engine::check_rocket_replenish()
00322 {
00323     if ((ammo < 3) &&                       // Checks if player doesn't already have 3 rockets.
00324         (rocket_regen_trigger == false)) {  // Checks if a rocket hasn't already been replenished this wave. (to prevent spamming)
00325             if ((wave_counter == 5) ||      // Checks if the game is at a certain wave:
00326                 (wave_counter == 10) ||
00327                 (wave_counter == 15) ||
00328                 (wave_counter == 20) ||
00329                 (wave_counter == 25) ||
00330                 (wave_counter == 30) ||
00331                 (wave_counter == 50) ||
00332                 (wave_counter == 75) ||
00333                 (wave_counter == 100) ||
00334                 (wave_counter == 150) ||
00335                 (wave_counter == 200)) {        
00336             ammo = ammo + 1;                // Adds a rocket to the inventory.
00337             rocket_regen_trigger = true;    // Sets the trigger to show a rocket has already been replenished this wave.
00338             printf("A rocket has been regenerated. Current number of rockets: %d \n", ammo);
00339             }     
00340     }
00341 }
00342 
00343 
00344 // Checks if it is time for the star to be replenished:
00345 
00346 void Engine::check_star_replenish()
00347 {
00348     if ((star == false) &&                  // Checks if player doesn't already have a star.
00349         (star_regen_trigger == false))      // Checks if a star hasn't already been replenished this wave. (to prevent spamming)
00350     {    
00351             if ((wave_counter == 5) ||      // Checks if the game is at a certain wave:
00352                 (wave_counter == 25) ||
00353                 (wave_counter == 50) ||
00354                 (wave_counter == 100) ||
00355                 (wave_counter == 150) ||
00356                 (wave_counter == 200)) 
00357             {        
00358             star = true;                    // Adds the star to the inventory.
00359             star_regen_trigger = true;      // Sets the trigger to show the star has already been replenished this wave.
00360             printf("%s \n", "A star has been regenerated."); 
00361             }     
00362     }
00363 }
00364 
00365 
00366 // Level two sequence, occurs if wave 5 is reached:
00367 
00368 void Engine::check_level_two(N5110 &lcd, Gamepad &pad)
00369 {
00370     if (wave_counter == 5) 
00371     {
00372         lcd.drawRect(0,0,84,48,FILL_WHITE);
00373         lcd.printString(" Nice! Level 2",0,1);
00374         lcd.printString("  Press Back!  ",0,4);
00375         lcd.refresh();
00376         wait(1);
00377         
00378         while (pad.check_event(Gamepad::BACK_PRESSED) == false) {   // Waits until the back button is pressed.
00379             wait(0.1);
00380         }
00381         
00382         init(LEVEL_TWO, lcd, pad, collisions, wave_counter, ammo, star, pauses);    // Initializes the ships at an elevated speed.
00383         wave_counter = 6;               // Increments the wave counter.
00384         printf("%s \n", "Level two has been reached.");
00385     }
00386 }
00387 
00388 
00389 // Level three sequence, occurs if wave 25 is reached:
00390 
00391 void Engine::check_level_three(N5110 &lcd, Gamepad &pad)
00392 {
00393     if (wave_counter == 25) 
00394     {
00395         lcd.drawRect(0,0,84,48,FILL_WHITE);
00396         lcd.printString(" Nice! Level 3",0,1);
00397         lcd.printString("  Press Back!  ",0,4);
00398         lcd.refresh();
00399         wait(1);
00400         
00401         while (pad.check_event(Gamepad::BACK_PRESSED) == false) {
00402             wait(0.1);
00403         }
00404         
00405         init(LEVEL_THREE, lcd, pad, collisions, wave_counter, ammo, star, pauses);
00406         wave_counter = 26;
00407         printf("%s \n", "Level three has been reached.");
00408     }
00409 }
00410 
00411 
00412 // Level three sequence, occurs if wave 50 is reached:
00413 
00414 void Engine::check_level_four(N5110 &lcd, Gamepad &pad)
00415 {
00416     if (wave_counter == 50) 
00417     {
00418         lcd.drawRect(0,0,84,48,FILL_WHITE);
00419         lcd.printString(" Nice! Level 4",0,1);
00420         lcd.printString("  Press Back!  ",0,4);
00421         lcd.refresh();
00422         wait(1);
00423         
00424         while (pad.check_event(Gamepad::BACK_PRESSED) == false) {
00425             wait(0.1);
00426         }
00427         
00428         init(LEVEL_FOUR, lcd, pad, collisions, wave_counter, ammo, star, pauses);
00429         wave_counter = 51;
00430         printf("%s \n", "Level four has been reached.");
00431     }
00432 }
00433 
00434 
00435 // Level five sequence, occurs if wave 100 is reached:
00436 
00437 void Engine::check_level_five(N5110 &lcd, Gamepad &pad)
00438 {
00439     if (wave_counter == 100) 
00440     {
00441         lcd.drawRect(0,0,84,48,FILL_WHITE);
00442         lcd.printString(" 5. Good Luck!",0,1);
00443         lcd.printString("  Press Back!  ",0,4);
00444         lcd.refresh();
00445         wait(1);
00446         
00447         while (pad.check_event(Gamepad::BACK_PRESSED) == false) {
00448             wait(0.1);
00449         }
00450         
00451         init(LEVEL_FIVE, lcd, pad, collisions, wave_counter, ammo, star, pauses);
00452         wave_counter = 101;
00453         printf("%s \n", "Level five has been reached.");
00454     }
00455 }
00456 
00457 
00458 // Pause sequence, checks if the game has been paused/unpaused
00459 
00460 void Engine::check_pause(N5110 &lcd, Gamepad &pad)
00461 {   
00462     if ((pad.check_event(Gamepad::START_PRESSED) == true) &&  // Checks if the start button has been pressed.
00463         (pauses > 0))       // Checks if the player has remaining pauses.
00464     {   
00465         printf("%s \n", "The game has been paused.");   
00466         while (pad.check_event(Gamepad::START_PRESSED) == false) {  
00467         // Flashes LEDs, switches between inverse and normal LCD modes, and waits until start button is pressed (unpause):
00468             pad.leds_on();      
00469             lcd.inverseMode();
00470             wait(0.5);
00471             pad.leds_off();
00472             lcd.normalMode();
00473             wait(0.5);
00474         }
00475     pauses = pauses - 1;    // Takes a pause from the player.
00476     printf("%s \n", "The game has been unpaused.");
00477     }
00478 }
00479 
00480 
00481 // Checks if the LCD's display mode has been toggled:
00482 
00483 void Engine::check_mode_toggle(N5110 &lcd, Gamepad &pad)
00484 {
00485     if (pad.check_event(Gamepad::R_PRESSED) == true) {  // Checks if right button is pressed.
00486             lcd.normalMode();                           // Sets the LCD to normal mode.
00487             pad.tone(1000.0,0.2);
00488             printf("%s \n", "Normal LCD mode has been toggled on.");
00489     }
00490     
00491     if (pad.check_event(Gamepad::L_PRESSED) == true) {  // Checks if left button is pressed.
00492             lcd.inverseMode();                          // Sets the LCD to inverse mode.
00493             pad.tone(1000.0,0.2);
00494             printf("%s \n", "Inverse LCD mode has been toggled on.");
00495     }
00496 }
00497 
00498 
00499 // Game over sequence, ends game if health is below zero:
00500 
00501 void Engine::check_gameover(N5110 &lcd, Gamepad &pad)
00502 {
00503     if (collisions >= 6) {                      // Checks if collisions are above 6 (health zero).
00504         lcd.drawRect(0,0,84,48,FILL_WHITE);     // Draws a dialog box.
00505         char buffer[14];
00506         int length = sprintf(buffer,"  Score: %2d",wave_counter);
00507         lcd.printString(buffer,0,2);            // Displays how many waves the player survived.
00508         lcd.printString("  You Lose! ",0,1);
00509         lcd.printString("  Press Back! ",0,4);
00510         lcd.refresh();
00511         
00512         printf("%s \n", "The player has lost.");    
00513         
00514         while (pad.check_event(Gamepad::BACK_PRESSED) == false) {   // Waits until the back button is pressed.
00515             wait(0.1);
00516         }
00517         
00518         printf("%s \n", "The player has restarted the game.");
00519         init(LEVEL_ONE, lcd, pad, 0, 0, 3, true, 3);      // Reinitializes the game at the lowest speed. Reinitializes variables.
00520     }
00521 }