Dmitrijs Griskovs / Mbed 2 deprecated el17dg

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers game.cpp Source File

game.cpp

00001 #include "mbed.h"
00002 #include "N5110.h"
00003 #include "Gamepad.h"
00004 #include "collision_lib.h"
00005 
00006 #include "models.h"
00007 #include "main.h"
00008 #include "game.h"
00009 #include "gameobject.h"
00010 
00011 #include "boss.h"
00012 #include "enemies.h"
00013 #include "constants.h"
00014 #include "stars.h"
00015 #include "player.h"
00016 #include "hud.h"
00017 #include "gameovermanager.h"
00018 
00019 
00020 const int increase_difficulty = 70;
00021 int GameGlobals::game_score = 0;
00022 int GameGlobals::score_count_for_difficulty = 0;
00023 int GameGlobals::player_lifes = 3;
00024 int GameGlobals::high_score = 0;
00025 bool GameGlobals::is_shield_on = false;
00026 int GameGlobals::score_count_for_boss_mode = 0;
00027 
00028 Boss boss;
00029 Enemies enemies;
00030 Enemy enemy;
00031 Stars stars;
00032 Player player;
00033 GameOverManager gameOverManager;
00034 
00035 CircleBounds circleBounds;
00036 Hud hud;
00037 
00038 
00039 void Game::updateAndDrawGameplay() {
00040     checkButtonToShoot();
00041     player.updateAndDraw();
00042     player.updateAndDrawBlasts();
00043     stars.updateAndDrawSmallStars();
00044     //stars.updateAndDrawMediumStars();
00045     stars.starsSpawnDelay();
00046     increaseGameDifficultyAndEnemySpawnDelay();
00047     hud.displayLifes();
00048     hud.drawScore();
00049     collideEnemiesAndBlasts();
00050     collideEnemiesBlastsAndPlayer();
00051     collideEnemiesAndPlayer();
00052     enemies.updateAndDrawEnemies();
00053     enemies.updateAndDrawEnemyBlasts();
00054     boss.updateAndDrawBossBlasts();
00055     
00056     if (checkForGameOver()) { game_state = GameState_gameover;}
00057     if (is_boss_active) { game_state = GameState_boss_cutscene;}
00058 }
00059 
00060 void Game::updateAndDrawGameover() {
00061     gameOverManager.updateAndDraw();
00062     if (gamepad.check_event(gamepad.Y_PRESSED) && !gameOverManager.isPlayingAnimation()) {
00063         gameOverManager.reset();
00064         game_state = GameState_newgame;
00065     }
00066 }
00067 
00068 void Game::updateAndDrawBossCutscene() {
00069     boss.updateCutscene();
00070     enemies.updateAndDrawEnemyBlasts();
00071     boss.draw();
00072     player.draw();
00073     stars.updateAndDrawSmallStars();
00074     stars.updateAndDrawMediumStars();
00075     if (boss.isFinishedCutscene()) {
00076         game_state = GameState_boss_gameplay;
00077         boss.resetCutscene(); 
00078     }
00079 }
00080 
00081 void Game::updateAndDrawBossGameplay() {
00082     checkButtonToShoot();
00083     enemies.updateAndDrawEnemyBlasts();
00084     player.updateAndDraw();
00085     player.updateAndDrawBlasts();
00086     stars.updateAndDrawSmallStars();
00087     stars.starsSpawnDelay();
00088     hud.displayLifes();
00089     hud.drawScore();
00090     boss.updateAndDrawBossBlasts();
00091     collideBossAndPlayerBlasts();
00092     collideBossBlastsAndPlayer();
00093     is_boss_active = boss.updateAndDrawBoss();
00094     if (checkForGameOver()) { game_state = GameState_gameover;}
00095     if (!is_boss_active) { game_state = GameState_gameplay;}
00096 }
00097 
00098 /**
00099   * This is the main function of game.cpp, where the actual gameplay happens.
00100   * Here all other functions are activeated, and when the player dies, it
00101   * returns back to main menu "main.cpp". 
00102   */
00103 bool Game::updateAndDraw() {
00104     if (game_state == GameState_newgame) {
00105         #ifdef DEBUGel17dg
00106         printf("start game \n");
00107         #endif
00108         startNewGame();
00109     }
00110     if (game_state == GameState_gameplay) { updateAndDrawGameplay(); }
00111     else if (game_state == GameState_boss_cutscene) { updateAndDrawBossCutscene(); }
00112     else if (game_state == GameState_boss_gameplay) { updateAndDrawBossGameplay(); }
00113     else if (game_state == GameState_gameover) { updateAndDrawGameover(); }
00114     
00115     return checkIfNeedsToReturnToMenu();
00116 }
00117 
00118 void Game::checkButtonToShoot(){
00119     if (gamepad.check_event(gamepad.X_PRESSED) && !GameGlobals::is_shield_on){
00120         // Checking the button second time to prevent double blast.
00121         gamepad.check_event(gamepad.X_PRESSED); 
00122         player.fireNewBlast();
00123         gamepad.tone(200,0.1);
00124     }
00125 }
00126 
00127 /**
00128   * This function checks whether the requirments for the collision of the two objects,
00129   * are met. When those requirments are met the collision of two objects function will
00130   * be checking wheter the boundaries of the objects colide. If they do, the blast
00131   * becomes inactive, in game score increases and enemy dies.
00132   */
00133 void Game::collideEnemiesAndBlasts() {
00134     for (int i = 0; i < enemies.max_enemies; ++i) {
00135         for (int j = 0; j < player.max_player_blasts; ++j) {
00136             Enemy& enemy = enemies.enemies[i];
00137             GameObject& blast = player.blasts[j];
00138             if (enemy.active && !enemy.dead && blast.active) {
00139                 bool collision = circleBounds.circleCollideTwoObjects(
00140                     enemy.pos, enemies.enemy_bounds, 
00141                     blast.pos, player.blast_bounds
00142                 );
00143                 if (collision) {
00144                     enemy.die();
00145                     #ifdef DEBUGel17dg
00146                     printf("enemy got hit and dies");
00147                     #endif
00148                     GameGlobals::game_score += 30;
00149                     GameGlobals::score_count_for_difficulty +=30;
00150                     GameGlobals::score_count_for_boss_mode += 30;
00151                     blast.active = false;
00152                 }
00153             }
00154         }
00155     }
00156 }
00157 
00158 /**
00159   * This code does the same work as the one before but with two other objects.
00160   * It checks whether the requirments for the collision of the two objects,
00161   * are met. When those requirments are met the collision of two objects function will
00162   * be checking wheter the boundaries of the objects colide. If they do, the blast
00163   * becomes inactive, in game score increases and enemy dies.
00164   */
00165 void Game::collideEnemiesBlastsAndPlayer() {
00166     for (int i = 0; i < enemies.max_enemies; ++i) {
00167         GameObject& blast = enemies.enemy_blasts[i];
00168         if (blast.active) {
00169             bool collision = circleBounds.circleCollideTwoObjects(
00170                 player.pos, player.player_bounds,
00171                 blast.pos, enemies.enemy_blast_bounds
00172             );
00173             if (collision) {
00174                 if (!GameGlobals::is_shield_on){
00175                     gamepad.tone(423,0.4); 
00176                     GameGlobals::player_lifes -= 1;
00177                     #ifdef DEBUGel17dg
00178                     printf("lost a life from blast. left: %i \n", GameGlobals::player_lifes);
00179                     #endif
00180                     blast.active = false;
00181                 }else{
00182                     blast.active = false;
00183                     gamepad.tone(700,0.6);
00184                 }
00185             }
00186         }
00187     } 
00188 }
00189 
00190 /**
00191   * This code does the same work as the one before but with two other object.
00192   * of enemy ship and the player's ship
00193   */
00194 void Game::collideEnemiesAndPlayer() {
00195     for (int i = 0; i < enemies.max_enemies; ++i) {
00196         Enemy& enemy = enemies.enemies[i];
00197         if (enemy.active && !enemy.dead) {
00198             bool collision = circleBounds.circleCollideTwoObjects(
00199                 player.pos, player.player_bounds,
00200                 enemy.pos, enemies.enemy_bounds
00201             );
00202             if (collision) {
00203                 GameGlobals::player_lifes -= 1;
00204                
00205                 enemy.die();
00206                 #ifdef DEBUGel17dg
00207                 printf("enemy got hit from collsion and dies");
00208                 printf("lost a life from enemy col. left: %i \n", GameGlobals::player_lifes);
00209                 #endif
00210             }
00211         }
00212     } 
00213 }
00214 
00215 void Game::collideBossAndPlayerBlasts() {
00216     for (int i = 0; i < player.max_player_blasts; ++i) {
00217         GameObject& blast = player.blasts[i];
00218         if (blast.active) {
00219             bool collision = circleBounds.circleCollideTwoObjects(
00220                 boss.pos, boss.boss_bounds,
00221                 blast.pos, player.blast_bounds
00222             );
00223             if (collision) {
00224                 boss.boss_lives -= 1;
00225                 gamepad.tone(123,0.4);
00226                 blast.active = false;
00227                 #ifdef DEBUGel17dg
00228                 printf("boss has. left: %i \n", boss.boss_lives);
00229                 #endif 
00230             }
00231         }
00232     } 
00233 }
00234 
00235 void Game::collideBossBlastsAndPlayer() {
00236     for (int i = 0; i < boss.max_boss_blasts; ++i) {
00237         GameObject& blast = boss.boss_blasts[i];
00238         if (blast.active) {
00239             bool collision = circleBounds.circleCollideTwoObjects(
00240                 player.pos, player.player_bounds,
00241                 blast.pos, boss.boss_blast_bounds
00242             );
00243             #ifdef DEBUGel17dg
00244             printf("player pos:%i,%i; offset:%i,%i; radius:%f.3; \n", player.pos.x, player.pos.y, player.player_bounds.center.x, player.player_bounds.center.y, player.player_bounds.radius);
00245             printf("blas pos:%i,%i; offset:%i,%i; radius:%f.3; \n", blast.pos.x, blast.pos.y, boss.boss_blast_bounds.center.x, boss.boss_blast_bounds.center.y, boss.boss_blast_bounds.radius);
00246             #endif 
00247             if (collision) {
00248                 if (!GameGlobals::is_shield_on){
00249                     
00250                     gamepad.tone(423,0.4); 
00251                     GameGlobals::player_lifes -= 1;
00252                     blast.active = false;
00253                     #ifdef DEBUGel17dg
00254                     printf("collision happened;\n");
00255                     printf("lost a life from blast. left: %i \n", GameGlobals::player_lifes);
00256                     #endif
00257                 }else{
00258                     blast.active = false;
00259                     gamepad.tone(700,0.6);
00260                 }
00261             }
00262         }
00263     } 
00264 }
00265 
00266 /**
00267     * This function resets all the values to their intial states when the game is
00268     * first began when the player dies and wants to restart the game.
00269     * It does not reset the values when the game is paused.
00270     */
00271 void Game::startNewGame() {
00272     is_boss_active = false;
00273     game_state = GameState_gameplay;
00274     player.pos.x = 0; //player was defined in player.h
00275     player.pos.y = 24;
00276     stars.stars_delay = 0;
00277     enemy_ship_delay_max = 40;
00278     enemy_ship_delay_counter = enemy_ship_delay_max;
00279     GameGlobals::is_shield_on = false;
00280     GameGlobals::game_score = 0;
00281     GameGlobals::score_count_for_difficulty = 0;
00282     GameGlobals::player_lifes = 3;
00283     GameGlobals::score_count_for_boss_mode = 0;
00284     hud.resetRedLed();
00285     enemies.enemy_blast_speed = 3;
00286     enemy.enemy_speed = 1;
00287     #ifdef DEBUGel17dg
00288     printf("startNewGame\n");
00289      
00290     #endif 
00291     for (int i = 0; i < enemies.max_enemies; ++i) {
00292         enemies.enemies[i].active = false;
00293     }
00294     for (int i = 0; i < player.max_player_blasts; ++i) {
00295         player.blasts[i].active = false;
00296     }
00297     for (int i = 0; i < enemies.max_enemy_blasts; ++i) {
00298         enemies.enemy_blasts[i].active = false;
00299     }
00300      for (int i = 0; i < boss.max_boss_blasts; ++i) {
00301         boss.boss_blasts[i].active = false;
00302     }
00303     gamepad.check_event(gamepad.START_PRESSED);
00304 }
00305 
00306 /**
00307     * A function tbat delays enemy spawn on low game score.
00308     * It decreases the enemy spawn delay as in game score increases.
00309     * The enemy spawn delay is located in game.cpp because the game difficulty
00310     * depends on the on how fast enemy appears.
00311     */
00312 void Game::increaseGameDifficultyAndEnemySpawnDelay(){
00313     if  (enemy_ship_delay_counter <= 0){ 
00314         enemies.spawnNewEnemy();
00315         enemy_ship_delay_counter = enemy_ship_delay_max;
00316     }
00317     else { enemy_ship_delay_counter -= 1;}
00318     
00319     if (enemy_ship_delay_max >= 4 && GameGlobals::score_count_for_difficulty >= increase_difficulty){
00320         //decrease enemy delay spawn.
00321         enemy_ship_delay_max -= 3;
00322         if (enemy_ship_delay_max <= 20 && enemy_ship_delay_max >= 15){
00323             enemies.enemy_blast_speed += 1;
00324             enemy.enemy_speed += 1;   
00325         }
00326         GameGlobals::score_count_for_difficulty = 0;   
00327     }
00328     if (GameGlobals::score_count_for_boss_mode >= 400){
00329         is_boss_active = true; 
00330         lcd.inverseMode();
00331     }
00332 }
00333 
00334 bool Game::forceShildActivate(){
00335     if (gamepad.check_event(gamepad.R_PRESSED)){
00336        GameGlobals::is_shield_on = !GameGlobals::is_shield_on; 
00337     }   
00338     return GameGlobals::is_shield_on;
00339 }
00340 
00341 /**
00342     * This is a single line function to set the player lifes to 0 when the.
00343     * game is over. 
00344     */
00345 bool Game::checkForGameOver() {
00346     return GameGlobals::player_lifes <= 0;
00347 }
00348 
00349 /**  This small statment checks whether the pause button was pressed or not.
00350   * If it was pressed, then the game will go back to main menu and will save 
00351   * the current status of the object until the game is continued.
00352   */
00353 bool Game::checkIfNeedsToReturnToMenu(){
00354     bool want_to_pause = false;
00355 
00356     if (gamepad.check_event(gamepad.START_PRESSED)){
00357         #ifdef DEBUGel17dg
00358         printf("game paused\n");
00359         #endif
00360         gamepad.check_event(gamepad.START_PRESSED);
00361         want_to_pause = true;
00362     }
00363     return want_to_pause;
00364 }