ELEC2645 (2018/19) / Mbed 2 deprecated el17dg

Dependencies:   mbed

Fork of el17dg by Dmitrijs Griskovs

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers boss.h Source File

boss.h

00001 #ifndef BOSS_H
00002 #define BOSS_H
00003 
00004 #include "constants.h"
00005 
00006 /** 
00007 * Boss Class
00008 * @brief A class to describe the states of the boss ship.
00009 * @author Dmitrijs Griskovs
00010 * @date 30/04/2019
00011 */
00012 class Boss : public GameObject {
00013 public:
00014     /**
00015      * @brief Maximum boss blasts on the screen.
00016      */
00017     static const int max_boss_blasts = 5; 
00018 
00019 
00020     GameObject boss_blasts[max_boss_blasts];
00021     CircleBounds boss_bounds;
00022     CircleBounds boss_blast_bounds;
00023     
00024     /** 
00025      * Constructor 
00026      * Sets values for the boss' sprite body circle area, the blast circle 
00027      * area and the circle radius for collsion callculations. Also, resets the
00028      * cutscene.
00029      */ 
00030     Boss() {
00031         boss_bounds.center.x = 5;
00032         boss_bounds.center.y = 8;
00033         boss_bounds.radius = 10;
00034         
00035         boss_blast_bounds.center.x = 1;
00036         boss_blast_bounds.center.y = 0;
00037         boss_blast_bounds.radius = 1;
00038         
00039         switch_boss_y_dir = true;
00040         animation_counter = 0;
00041         resetCutscene();  
00042     }
00043     
00044     /** 
00045      * @brief Updates and draws the boss blasts accross the screen.
00046      */
00047      void updateAndDrawBossBlasts() {
00048         for (int i = 0; i < max_boss_blasts; ++i) {
00049             if (boss_blasts[i].active) {
00050                 boss_blasts[i].pos.x -= boss_blast_speed;
00051                 if (boss_blasts[i].pos.x <= 0){
00052                     boss_blasts[i].active = false;
00053                     continue;
00054                 }
00055                 drawSprite(boss_blasts[i].pos, blast_sprite);
00056             }
00057         }
00058     }
00059     /** 
00060      * @brief Updates and draws the boss.
00061      * @details this function is monitored in game.cpp and when the boss becomes
00062      * inactive, the gameplay would switch from boss to normal.
00063      * @returns bool active, when the boss is out of lives
00064      */
00065     bool updateAndDrawBoss(){
00066         if(switch_boss_y_dir) { pos.y += 1;}
00067         else                  { pos.y -= 1;}
00068         if (pos.y >= (game_area_height - enemy1_height)){ switch_boss_y_dir = false;}
00069         else if (pos.y <= game_area_y)                  { switch_boss_y_dir = true;}
00070         blast_countdown -= 1;
00071         if (blast_countdown <= 0) {
00072             fireNewBlast(pos.x, pos.y + 2);
00073             fireNewBlast(pos.x, pos.y + enemy1_height - 2);
00074             blast_countdown = 10;
00075         }
00076         if(!dead() && active){ draw();}
00077         else{
00078             GameGlobals::game_score += 300;
00079             GameGlobals::score_count_for_boss_mode = 0;
00080             updateAndDrawDeathExplosion();
00081             lcd.normalMode();
00082         }
00083         return active;
00084     }
00085     /** 
00086      * @brief Updates and draws the boss' cutscene of entering the game.
00087      * @details It freezes the screen until the boss is set on the screen. Also,
00088      * it sets its position and number of lives.
00089      * @returns bool active, when the boss is out of lives
00090      */
00091     void updateCutscene() {
00092         if (!started_cutscene) {
00093             started_cutscene = true;
00094             pos.y = screen_height/2 - (enemy1_height/2);
00095             pos.x = screen_width;
00096             animation_counter = 0;
00097             active = true;
00098             boss_lives = 10;
00099             dead_counter = 5;
00100             DG_PRINTF("boss lives set to: %i \n", boss_lives);
00101             return;
00102         }
00103         if (animation_counter < animation_length) {
00104             pos.x -= 1;
00105             animation_counter++;
00106         }    
00107     }
00108     
00109     /** @brief draws boss' sprite.*/
00110     void draw() {  drawSpriteOnTop(pos, enemy1_sprite);}
00111     /** @brief resets the boss' cutscene.*/
00112     void resetCutscene() { started_cutscene = false; }
00113     /** 
00114      * @returns bool true 
00115      * @brief It starts the boss fight sequence when the cutscene is finished.
00116      */
00117     bool isFinishedCutscene() { return animation_counter >= animation_length; }
00118     /**
00119      * @var int boss_lives 
00120      * @brief contains boss' lives.
00121      */
00122     int boss_lives;
00123     
00124 private:
00125     void updateAndDrawDeathExplosion() {
00126         for(int dead_counter; dead_counter >= 0; dead_counter--){
00127             if (dead_counter > 0) {
00128                 if (dead_counter == 4){    
00129                     drawSpriteOnTop(pos, enemy1_quarter_exploded_sprite);
00130                 } else if (dead_counter == 3){
00131                     drawSpriteOnTop(pos, enemy1_half_exploded_sprite);
00132                 } else if (dead_counter == 2){
00133                     drawSpriteOnTop(pos, enemy1_second_quarter_exploded_sprite);
00134                 } else if (dead_counter == 1){
00135                     drawSpriteOnTop(pos, enemy1_fully_exploded_sprite);
00136                 }
00137             } else {
00138                 active = false;
00139                 DG_PRINTF("boss died \n");
00140             }
00141         }
00142     } 
00143 
00144     /** 
00145      * @brief Spawns a blast at the position of the boss.
00146      * @param x (int x) to give x position of the boss blast.
00147      * @param y (int y) to give y position of the boss blast.
00148      * @details For this function the parameters are required to be able to spawn
00149      * two independed from each other blasts at the same time and different
00150      * positions.
00151      */
00152     bool fireNewBlast(int x, int y) {
00153         // Search the array of blasts if inactive we can use it.
00154         int found = -1;
00155         for (int i = 0; i < max_boss_blasts; ++i) {
00156             if (!boss_blasts[i].active) {
00157                 found = i;
00158                 break;
00159             }
00160         }   
00161         if (found != -1) {
00162             boss_blasts[found].active = true;
00163             boss_blasts[found].pos.x = x;
00164             boss_blasts[found].pos.y = y;
00165             gamepad.tone(500,0.1);
00166             return true;
00167         }
00168         return false;
00169     }
00170     static const int boss_y_speed = 2;
00171     static const int boss_blast_speed = 4;
00172     static const int animation_length = 20;
00173     bool dead(){return boss_lives == 0;}
00174     bool started_cutscene;
00175     bool switch_boss_y_dir;
00176     int blast_countdown;
00177     int animation_counter;
00178     int dead_counter;
00179 };
00180 
00181 #endif