Initial publish
Dependencies: mbed
Fork of el17dg by
game/boss.h@40:e3bbda7444fa, 2019-05-07 (annotated)
- Committer:
- Noximilien
- Date:
- Tue May 07 15:22:35 2019 +0000
- Revision:
- 40:e3bbda7444fa
- Parent:
- 39:ca77a6d574e6
The Final, Submission Version. I have read and agreed to the academic integrity. SID:201160286
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Noximilien | 33:c623c6d5ed16 | 1 | #ifndef BOSS_H |
Noximilien | 33:c623c6d5ed16 | 2 | #define BOSS_H |
Noximilien | 33:c623c6d5ed16 | 3 | |
Noximilien | 33:c623c6d5ed16 | 4 | #include "constants.h" |
Noximilien | 33:c623c6d5ed16 | 5 | |
Noximilien | 34:754915ce9de5 | 6 | /** |
Noximilien | 34:754915ce9de5 | 7 | * Boss Class |
Noximilien | 34:754915ce9de5 | 8 | * @brief A class to describe the states of the boss ship. |
Noximilien | 34:754915ce9de5 | 9 | * @author Dmitrijs Griskovs |
Noximilien | 34:754915ce9de5 | 10 | * @date 30/04/2019 |
Noximilien | 34:754915ce9de5 | 11 | */ |
Noximilien | 33:c623c6d5ed16 | 12 | class Boss : public GameObject { |
Noximilien | 33:c623c6d5ed16 | 13 | public: |
Noximilien | 33:c623c6d5ed16 | 14 | /** |
Noximilien | 37:6a2bf4488022 | 15 | * @brief Maximum boss blasts on the screen. |
Noximilien | 33:c623c6d5ed16 | 16 | */ |
Noximilien | 37:6a2bf4488022 | 17 | static const int max_boss_blasts = 5; |
Noximilien | 33:c623c6d5ed16 | 18 | |
Noximilien | 33:c623c6d5ed16 | 19 | |
Noximilien | 34:754915ce9de5 | 20 | GameObject boss_blasts[max_boss_blasts]; |
Noximilien | 33:c623c6d5ed16 | 21 | CircleBounds boss_bounds; |
Noximilien | 33:c623c6d5ed16 | 22 | CircleBounds boss_blast_bounds; |
Noximilien | 34:754915ce9de5 | 23 | |
Noximilien | 34:754915ce9de5 | 24 | /** |
Noximilien | 34:754915ce9de5 | 25 | * Constructor |
Noximilien | 34:754915ce9de5 | 26 | * Sets values for the boss' sprite body circle area, the blast circle |
Noximilien | 34:754915ce9de5 | 27 | * area and the circle radius for collsion callculations. Also, resets the |
Noximilien | 34:754915ce9de5 | 28 | * cutscene. |
Noximilien | 34:754915ce9de5 | 29 | */ |
Noximilien | 33:c623c6d5ed16 | 30 | Boss() { |
Noximilien | 33:c623c6d5ed16 | 31 | boss_bounds.center.x = 5; |
Noximilien | 33:c623c6d5ed16 | 32 | boss_bounds.center.y = 8; |
Noximilien | 33:c623c6d5ed16 | 33 | boss_bounds.radius = 10; |
Noximilien | 33:c623c6d5ed16 | 34 | |
Noximilien | 34:754915ce9de5 | 35 | boss_blast_bounds.center.x = 1; |
Noximilien | 34:754915ce9de5 | 36 | boss_blast_bounds.center.y = 0; |
Noximilien | 33:c623c6d5ed16 | 37 | boss_blast_bounds.radius = 1; |
Noximilien | 33:c623c6d5ed16 | 38 | |
Noximilien | 34:754915ce9de5 | 39 | switch_boss_y_dir = true; |
Noximilien | 34:754915ce9de5 | 40 | animation_counter = 0; |
Noximilien | 34:754915ce9de5 | 41 | resetCutscene(); |
Noximilien | 33:c623c6d5ed16 | 42 | } |
Noximilien | 33:c623c6d5ed16 | 43 | |
Noximilien | 35:172db1608332 | 44 | /** |
Noximilien | 35:172db1608332 | 45 | * @brief Updates and draws the boss blasts accross the screen. |
Noximilien | 35:172db1608332 | 46 | */ |
Noximilien | 35:172db1608332 | 47 | void updateAndDrawBossBlasts() { |
Noximilien | 35:172db1608332 | 48 | for (int i = 0; i < max_boss_blasts; ++i) { |
Noximilien | 35:172db1608332 | 49 | if (boss_blasts[i].active) { |
Noximilien | 35:172db1608332 | 50 | boss_blasts[i].pos.x -= boss_blast_speed; |
Noximilien | 35:172db1608332 | 51 | if (boss_blasts[i].pos.x <= 0){ |
Noximilien | 35:172db1608332 | 52 | boss_blasts[i].active = false; |
Noximilien | 35:172db1608332 | 53 | continue; |
Noximilien | 35:172db1608332 | 54 | } |
Noximilien | 35:172db1608332 | 55 | drawSprite(boss_blasts[i].pos, blast_sprite); |
Noximilien | 35:172db1608332 | 56 | } |
Noximilien | 35:172db1608332 | 57 | } |
Noximilien | 35:172db1608332 | 58 | } |
Noximilien | 35:172db1608332 | 59 | /** |
Noximilien | 35:172db1608332 | 60 | * @brief Updates and draws the boss. |
Noximilien | 35:172db1608332 | 61 | * @details this function is monitored in game.cpp and when the boss becomes |
Noximilien | 35:172db1608332 | 62 | * inactive, the gameplay would switch from boss to normal. |
Noximilien | 35:172db1608332 | 63 | * @returns bool active, when the boss is out of lives |
Noximilien | 35:172db1608332 | 64 | */ |
Noximilien | 35:172db1608332 | 65 | bool updateAndDrawBoss(){ |
Noximilien | 35:172db1608332 | 66 | if(switch_boss_y_dir) { pos.y += 1;} |
Noximilien | 35:172db1608332 | 67 | else { pos.y -= 1;} |
Noximilien | 35:172db1608332 | 68 | if (pos.y >= (game_area_height - enemy1_height)){ switch_boss_y_dir = false;} |
Noximilien | 35:172db1608332 | 69 | else if (pos.y <= game_area_y) { switch_boss_y_dir = true;} |
Noximilien | 35:172db1608332 | 70 | blast_countdown -= 1; |
Noximilien | 35:172db1608332 | 71 | if (blast_countdown <= 0) { |
Noximilien | 35:172db1608332 | 72 | fireNewBlast(pos.x, pos.y + 2); |
Noximilien | 35:172db1608332 | 73 | fireNewBlast(pos.x, pos.y + enemy1_height - 2); |
Noximilien | 35:172db1608332 | 74 | blast_countdown = 10; |
Noximilien | 35:172db1608332 | 75 | } |
Noximilien | 35:172db1608332 | 76 | if(!dead() && active){ draw();} |
Noximilien | 35:172db1608332 | 77 | else{ |
Noximilien | 35:172db1608332 | 78 | GameGlobals::game_score += 300; |
Noximilien | 35:172db1608332 | 79 | GameGlobals::score_count_for_boss_mode = 0; |
Noximilien | 36:207ec7db8648 | 80 | updateAndDrawDeathExplosion(); |
Noximilien | 35:172db1608332 | 81 | lcd.normalMode(); |
Noximilien | 35:172db1608332 | 82 | } |
Noximilien | 35:172db1608332 | 83 | return active; |
Noximilien | 35:172db1608332 | 84 | } |
Noximilien | 35:172db1608332 | 85 | /** |
Noximilien | 35:172db1608332 | 86 | * @brief Updates and draws the boss' cutscene of entering the game. |
Noximilien | 35:172db1608332 | 87 | * @details It freezes the screen until the boss is set on the screen. Also, |
Noximilien | 35:172db1608332 | 88 | * it sets its position and number of lives. |
Noximilien | 35:172db1608332 | 89 | * @returns bool active, when the boss is out of lives |
Noximilien | 35:172db1608332 | 90 | */ |
Noximilien | 35:172db1608332 | 91 | void updateCutscene() { |
Noximilien | 35:172db1608332 | 92 | if (!started_cutscene) { |
Noximilien | 35:172db1608332 | 93 | started_cutscene = true; |
Noximilien | 35:172db1608332 | 94 | pos.y = screen_height/2 - (enemy1_height/2); |
Noximilien | 35:172db1608332 | 95 | pos.x = screen_width; |
Noximilien | 35:172db1608332 | 96 | animation_counter = 0; |
Noximilien | 35:172db1608332 | 97 | active = true; |
Noximilien | 35:172db1608332 | 98 | boss_lives = 10; |
Noximilien | 38:ef3968546d36 | 99 | dead_counter = 5; |
Noximilien | 37:6a2bf4488022 | 100 | DG_PRINTF("boss lives set to: %i \n", boss_lives); |
Noximilien | 35:172db1608332 | 101 | return; |
Noximilien | 35:172db1608332 | 102 | } |
Noximilien | 35:172db1608332 | 103 | if (animation_counter < animation_length) { |
Noximilien | 35:172db1608332 | 104 | pos.x -= 1; |
Noximilien | 35:172db1608332 | 105 | animation_counter++; |
Noximilien | 35:172db1608332 | 106 | } |
Noximilien | 35:172db1608332 | 107 | } |
Noximilien | 35:172db1608332 | 108 | |
Noximilien | 35:172db1608332 | 109 | /** @brief draws boss' sprite.*/ |
Noximilien | 35:172db1608332 | 110 | void draw() { drawSpriteOnTop(pos, enemy1_sprite);} |
Noximilien | 35:172db1608332 | 111 | /** @brief resets the boss' cutscene.*/ |
Noximilien | 35:172db1608332 | 112 | void resetCutscene() { started_cutscene = false; } |
Noximilien | 35:172db1608332 | 113 | /** |
Noximilien | 35:172db1608332 | 114 | * @returns bool true |
Noximilien | 35:172db1608332 | 115 | * @brief It starts the boss fight sequence when the cutscene is finished. |
Noximilien | 35:172db1608332 | 116 | */ |
Noximilien | 35:172db1608332 | 117 | bool isFinishedCutscene() { return animation_counter >= animation_length; } |
Noximilien | 35:172db1608332 | 118 | /** |
Noximilien | 35:172db1608332 | 119 | * @var int boss_lives |
Noximilien | 35:172db1608332 | 120 | * @brief contains boss' lives. |
Noximilien | 35:172db1608332 | 121 | */ |
Noximilien | 35:172db1608332 | 122 | int boss_lives; |
Noximilien | 35:172db1608332 | 123 | |
Noximilien | 35:172db1608332 | 124 | private: |
Noximilien | 36:207ec7db8648 | 125 | void updateAndDrawDeathExplosion() { |
Noximilien | 36:207ec7db8648 | 126 | for(int dead_counter; dead_counter >= 0; dead_counter--){ |
Noximilien | 36:207ec7db8648 | 127 | if (dead_counter > 0) { |
Noximilien | 36:207ec7db8648 | 128 | if (dead_counter == 4){ |
Noximilien | 36:207ec7db8648 | 129 | drawSpriteOnTop(pos, enemy1_quarter_exploded_sprite); |
Noximilien | 36:207ec7db8648 | 130 | } else if (dead_counter == 3){ |
Noximilien | 36:207ec7db8648 | 131 | drawSpriteOnTop(pos, enemy1_half_exploded_sprite); |
Noximilien | 36:207ec7db8648 | 132 | } else if (dead_counter == 2){ |
Noximilien | 36:207ec7db8648 | 133 | drawSpriteOnTop(pos, enemy1_second_quarter_exploded_sprite); |
Noximilien | 36:207ec7db8648 | 134 | } else if (dead_counter == 1){ |
Noximilien | 36:207ec7db8648 | 135 | drawSpriteOnTop(pos, enemy1_fully_exploded_sprite); |
Noximilien | 36:207ec7db8648 | 136 | } |
Noximilien | 36:207ec7db8648 | 137 | } else { |
Noximilien | 36:207ec7db8648 | 138 | active = false; |
Noximilien | 39:ca77a6d574e6 | 139 | DG_PRINTF("boss died \n"); |
Noximilien | 36:207ec7db8648 | 140 | } |
Noximilien | 36:207ec7db8648 | 141 | } |
Noximilien | 36:207ec7db8648 | 142 | } |
Noximilien | 35:172db1608332 | 143 | |
Noximilien | 35:172db1608332 | 144 | /** |
Noximilien | 35:172db1608332 | 145 | * @brief Spawns a blast at the position of the boss. |
Noximilien | 35:172db1608332 | 146 | * @param x (int x) to give x position of the boss blast. |
Noximilien | 35:172db1608332 | 147 | * @param y (int y) to give y position of the boss blast. |
Noximilien | 35:172db1608332 | 148 | * @details For this function the parameters are required to be able to spawn |
Noximilien | 35:172db1608332 | 149 | * two independed from each other blasts at the same time and different |
Noximilien | 35:172db1608332 | 150 | * positions. |
Noximilien | 35:172db1608332 | 151 | */ |
Noximilien | 34:754915ce9de5 | 152 | bool fireNewBlast(int x, int y) { |
Noximilien | 33:c623c6d5ed16 | 153 | // Search the array of blasts if inactive we can use it. |
Noximilien | 33:c623c6d5ed16 | 154 | int found = -1; |
Noximilien | 33:c623c6d5ed16 | 155 | for (int i = 0; i < max_boss_blasts; ++i) { |
Noximilien | 34:754915ce9de5 | 156 | if (!boss_blasts[i].active) { |
Noximilien | 33:c623c6d5ed16 | 157 | found = i; |
Noximilien | 33:c623c6d5ed16 | 158 | break; |
Noximilien | 33:c623c6d5ed16 | 159 | } |
Noximilien | 33:c623c6d5ed16 | 160 | } |
Noximilien | 33:c623c6d5ed16 | 161 | if (found != -1) { |
Noximilien | 34:754915ce9de5 | 162 | boss_blasts[found].active = true; |
Noximilien | 34:754915ce9de5 | 163 | boss_blasts[found].pos.x = x; |
Noximilien | 34:754915ce9de5 | 164 | boss_blasts[found].pos.y = y; |
Noximilien | 34:754915ce9de5 | 165 | gamepad.tone(500,0.1); |
Noximilien | 34:754915ce9de5 | 166 | return true; |
Noximilien | 33:c623c6d5ed16 | 167 | } |
Noximilien | 34:754915ce9de5 | 168 | return false; |
Noximilien | 33:c623c6d5ed16 | 169 | } |
Noximilien | 34:754915ce9de5 | 170 | static const int boss_y_speed = 2; |
Noximilien | 34:754915ce9de5 | 171 | static const int boss_blast_speed = 4; |
Noximilien | 36:207ec7db8648 | 172 | static const int animation_length = 20; |
Noximilien | 34:754915ce9de5 | 173 | bool dead(){return boss_lives == 0;} |
Noximilien | 34:754915ce9de5 | 174 | bool started_cutscene; |
Noximilien | 33:c623c6d5ed16 | 175 | bool switch_boss_y_dir; |
Noximilien | 34:754915ce9de5 | 176 | int blast_countdown; |
Noximilien | 34:754915ce9de5 | 177 | int animation_counter; |
Noximilien | 36:207ec7db8648 | 178 | int dead_counter; |
Noximilien | 33:c623c6d5ed16 | 179 | }; |
Noximilien | 33:c623c6d5ed16 | 180 | |
Noximilien | 33:c623c6d5ed16 | 181 | #endif |