Initial publish

Dependencies:   mbed

Fork of el17dg by Dmitrijs Griskovs

Committer:
Noximilien
Date:
Tue May 07 15:22:35 2019 +0000
Revision:
40:e3bbda7444fa
Parent:
38:ef3968546d36
The Final, Submission Version. I have read and agreed to the academic integrity. SID:201160286

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Noximilien 21:0eb394495b8a 1 #ifndef ENEMIES_H
Noximilien 21:0eb394495b8a 2 #define ENEMIES_H
Noximilien 21:0eb394495b8a 3
Noximilien 31:becb8f6bf7b7 4 /**
Noximilien 31:becb8f6bf7b7 5 * Enemy Class
Noximilien 31:becb8f6bf7b7 6 * @brief A class to describe the states of an enemy ship.
Noximilien 29:579e00b7f118 7 * @author Dmitrijs Griskovs
Noximilien 29:579e00b7f118 8 * @date 15/04/2019
Noximilien 24:0570cb4b92d7 9 */
Noximilien 21:0eb394495b8a 10 class Enemy : public GameObject {
Noximilien 21:0eb394495b8a 11 public:
Noximilien 34:754915ce9de5 12 Enemy() {
Noximilien 34:754915ce9de5 13 /** A bool that changes states between whehter to go up or down in y-direction.*/
Noximilien 34:754915ce9de5 14 switch_enemy_y_dir = false;
Noximilien 34:754915ce9de5 15 enemy_speed = 1;
Noximilien 34:754915ce9de5 16 }
Noximilien 31:becb8f6bf7b7 17 /**
Noximilien 31:becb8f6bf7b7 18 * @brief Enemy spawn function.
Noximilien 31:becb8f6bf7b7 19 * @details This function spawns an enemy on the right side of the screen
Noximilien 31:becb8f6bf7b7 20 * and at random position in the y-direction.
Noximilien 31:becb8f6bf7b7 21 */
Noximilien 21:0eb394495b8a 22 void spawn() {
Noximilien 21:0eb394495b8a 23 Point spawn_pos(screen_width, game_area_y + rand() % (game_area_height - enemy2_height));
Noximilien 21:0eb394495b8a 24 GameObject::spawn(spawn_pos);
Noximilien 21:0eb394495b8a 25 dead = false;
Noximilien 21:0eb394495b8a 26 dead_counter = 0;
Noximilien 21:0eb394495b8a 27 blast_countdown = 0;
Noximilien 21:0eb394495b8a 28 }
Noximilien 31:becb8f6bf7b7 29 /**
Noximilien 31:becb8f6bf7b7 30 * @brief enemy death sound and status reset.
Noximilien 31:becb8f6bf7b7 31 * @details Marks enemy as dead, so it can display explosion anation.
Noximilien 31:becb8f6bf7b7 32 */
Noximilien 21:0eb394495b8a 33 void die() {
Noximilien 27:f05f4e738ba9 34 gamepad.tone(123,0.3);
Noximilien 21:0eb394495b8a 35 dead = true;
Noximilien 37:6a2bf4488022 36 dead_counter = 6;
Noximilien 21:0eb394495b8a 37 }
Noximilien 31:becb8f6bf7b7 38
Noximilien 31:becb8f6bf7b7 39 /**
Noximilien 31:becb8f6bf7b7 40 * @brief Draws and updates enemy sprites on the screen and substracts the score
Noximilien 31:becb8f6bf7b7 41 * if the ship leaves the screen limits.
Noximilien 31:becb8f6bf7b7 42 *
Noximilien 31:becb8f6bf7b7 43 * @details The function draws this enemy ship on the screen, and
Noximilien 31:becb8f6bf7b7 44 * changes their x and y positions each time the function is called.
Noximilien 31:becb8f6bf7b7 45 * If ship is dead then it draws enemy explosion animation and then disables it.
Noximilien 31:becb8f6bf7b7 46 * Disables the ship when it leaves the screen limits and substracts
Noximilien 31:becb8f6bf7b7 47 * the in game score by -50.
Noximilien 31:becb8f6bf7b7 48 */
Noximilien 21:0eb394495b8a 49 void updateAndDraw() {
Noximilien 21:0eb394495b8a 50 pos.x -= enemy_speed;
Noximilien 31:becb8f6bf7b7 51 if (GameGlobals::game_score >= 200){
Noximilien 34:754915ce9de5 52 if (!switch_enemy_y_dir){pos.y -= 1;}
Noximilien 34:754915ce9de5 53 else if(switch_enemy_y_dir){pos.y += 1;}
Noximilien 32:5403bb974294 54 if (pos.y >= (game_area_height - enemy2_height)){
Noximilien 28:35af3843de8f 55 switch_enemy_y_dir = false;
Noximilien 28:35af3843de8f 56 }
Noximilien 32:5403bb974294 57 else if (pos.y <= game_area_y){
Noximilien 28:35af3843de8f 58 switch_enemy_y_dir = true;
Noximilien 28:35af3843de8f 59 }
Noximilien 28:35af3843de8f 60 }
Noximilien 29:579e00b7f118 61 if (!dead) { drawSprite(pos, enemy2_sprite);}
Noximilien 29:579e00b7f118 62 else { updateAndDrawDeathExplosion();}
Noximilien 29:579e00b7f118 63
Noximilien 21:0eb394495b8a 64 if (pos.x < 0) {
Noximilien 31:becb8f6bf7b7 65 GameGlobals::game_score -= 50;
Noximilien 21:0eb394495b8a 66 active = false;
Noximilien 21:0eb394495b8a 67 }
Noximilien 21:0eb394495b8a 68 }
Noximilien 36:207ec7db8648 69
Noximilien 35:172db1608332 70 /**
Noximilien 35:172db1608332 71 * @var bool dead
Noximilien 35:172db1608332 72 * @brief sets if to true when enemy is hit to draw explossion.
Noximilien 35:172db1608332 73 */
Noximilien 21:0eb394495b8a 74 bool dead;
Noximilien 35:172db1608332 75 /**
Noximilien 35:172db1608332 76 * @var int dead_counter
Noximilien 35:172db1608332 77 * @brief For drawing small explosion animatioin.
Noximilien 35:172db1608332 78 */
Noximilien 21:0eb394495b8a 79 int dead_counter;
Noximilien 35:172db1608332 80 /**
Noximilien 35:172db1608332 81 * @var int blast_countdown
Noximilien 35:172db1608332 82 * @brief A variable for delaying the enemy shots.
Noximilien 35:172db1608332 83 */
Noximilien 21:0eb394495b8a 84 int blast_countdown;
Noximilien 35:172db1608332 85 /**
Noximilien 35:172db1608332 86 * @var int enemy_speed
Noximilien 35:172db1608332 87 * @brief How fast should an enemy move.
Noximilien 35:172db1608332 88 */
Noximilien 34:754915ce9de5 89 int enemy_speed;
Noximilien 36:207ec7db8648 90 private:/**
Noximilien 36:207ec7db8648 91 * @brief Draws enemy explosion sprite
Noximilien 36:207ec7db8648 92 * @details Draws the enemy ships explosion sprites when the player's
Noximilien 36:207ec7db8648 93 * shot hits them or when the player collides with them.
Noximilien 36:207ec7db8648 94 * the animation consists of two sprites "Exploded" and "Half exploded".
Noximilien 36:207ec7db8648 95 */
Noximilien 36:207ec7db8648 96 void updateAndDrawDeathExplosion() {
Noximilien 36:207ec7db8648 97 if (dead_counter > 0) {
Noximilien 36:207ec7db8648 98 dead_counter--;
Noximilien 38:ef3968546d36 99 if (dead_counter > 2) {
Noximilien 36:207ec7db8648 100 drawSprite(pos, enemy2_half_exploded_sprite);
Noximilien 37:6a2bf4488022 101 } else {
Noximilien 36:207ec7db8648 102 drawSprite(pos, enemy2_exploded_sprite);
Noximilien 36:207ec7db8648 103 }
Noximilien 36:207ec7db8648 104 } else {
Noximilien 36:207ec7db8648 105 active = false;
Noximilien 36:207ec7db8648 106 }
Noximilien 36:207ec7db8648 107 }
Noximilien 34:754915ce9de5 108
Noximilien 34:754915ce9de5 109 bool switch_enemy_y_dir;
Noximilien 21:0eb394495b8a 110 };
Noximilien 21:0eb394495b8a 111
Noximilien 23:240bc00ef25b 112
Noximilien 31:becb8f6bf7b7 113 /**
Noximilien 31:becb8f6bf7b7 114 * Enemies Class
Noximilien 31:becb8f6bf7b7 115 * @brief The class manages all enemy ships.
Noximilien 31:becb8f6bf7b7 116 * @details Responsible for spawning new ships and holding and updating them
Noximilien 31:becb8f6bf7b7 117 * and controlling time intervals between enemy shots.
Noximilien 31:becb8f6bf7b7 118 * @author Dmitrijs Griskovs
Noximilien 31:becb8f6bf7b7 119 * @date 15/04/2019
Noximilien 31:becb8f6bf7b7 120 */
Noximilien 21:0eb394495b8a 121 class Enemies {
Noximilien 21:0eb394495b8a 122 public:
Noximilien 35:172db1608332 123 /**
Noximilien 35:172db1608332 124 * @var static const int max_enemies
Noximilien 35:172db1608332 125 * @brief Maximum enemies allowed on the screen
Noximilien 35:172db1608332 126 */
Noximilien 34:754915ce9de5 127 static const int max_enemies = 4;
Noximilien 35:172db1608332 128 /**
Noximilien 35:172db1608332 129 * @var static const int max_enemy_blasts
Noximilien 35:172db1608332 130 * @brief Maximum enemies' blasts allowed on the screen
Noximilien 35:172db1608332 131 */
Noximilien 34:754915ce9de5 132 static const int max_enemy_blasts = max_enemies*2;
Noximilien 34:754915ce9de5 133
Noximilien 23:240bc00ef25b 134 Enemy enemy_blasts[max_enemy_blasts];
Noximilien 23:240bc00ef25b 135 Enemy enemies[max_enemies];
Noximilien 23:240bc00ef25b 136 CircleBounds enemy_bounds;
Noximilien 23:240bc00ef25b 137 CircleBounds enemy_blast_bounds;
Noximilien 23:240bc00ef25b 138
Noximilien 31:becb8f6bf7b7 139 /**
Noximilien 34:754915ce9de5 140 * Constructor
Noximilien 34:754915ce9de5 141 * Sets values for the enemy's sprite body circle area, the blast circle
Noximilien 34:754915ce9de5 142 * area and the circle radius for collsion callculations.
Noximilien 31:becb8f6bf7b7 143 */
Noximilien 21:0eb394495b8a 144 Enemies () {
Noximilien 21:0eb394495b8a 145 enemy_bounds.center.x = 5;
Noximilien 21:0eb394495b8a 146 enemy_bounds.center.y = 3;
Noximilien 26:676874c42883 147 enemy_bounds.radius = 6;
Noximilien 21:0eb394495b8a 148
Noximilien 21:0eb394495b8a 149 enemy_blast_bounds.center.x = 0;
Noximilien 21:0eb394495b8a 150 enemy_blast_bounds.center.y = 1;
Noximilien 21:0eb394495b8a 151 enemy_blast_bounds.radius = 1;
Noximilien 34:754915ce9de5 152
Noximilien 34:754915ce9de5 153 enemy_blast_speed = 2;
Noximilien 21:0eb394495b8a 154 }
Noximilien 31:becb8f6bf7b7 155
Noximilien 31:becb8f6bf7b7 156 /**
Noximilien 31:becb8f6bf7b7 157 * @brief This function spawns a new enemy on the screen.
Noximilien 31:becb8f6bf7b7 158 * @details It spawns a new enemy on the screen when there is a free space
Noximilien 31:becb8f6bf7b7 159 * in the enemy aray.
Noximilien 31:becb8f6bf7b7 160 */
Noximilien 21:0eb394495b8a 161 void spawnNewEnemy() {
Noximilien 21:0eb394495b8a 162 int found = -1;
Noximilien 21:0eb394495b8a 163 for (int i = 0; i < max_enemies; ++i) {
Noximilien 21:0eb394495b8a 164 if (!enemies[i].active) {
Noximilien 21:0eb394495b8a 165 found = i;
Noximilien 21:0eb394495b8a 166 break;
Noximilien 21:0eb394495b8a 167 }
Noximilien 21:0eb394495b8a 168 }
Noximilien 21:0eb394495b8a 169
Noximilien 21:0eb394495b8a 170 if (found != -1) {
Noximilien 21:0eb394495b8a 171 enemies[found].spawn();
Noximilien 21:0eb394495b8a 172 }
Noximilien 21:0eb394495b8a 173 }
Noximilien 31:becb8f6bf7b7 174
Noximilien 31:becb8f6bf7b7 175 /**
Noximilien 31:becb8f6bf7b7 176 * @brief Draws the ships and the blasts.
Noximilien 31:becb8f6bf7b7 177 * @details Updates and draws all active enemy ships and decides when they
Noximilien 31:becb8f6bf7b7 178 * should fire blasts.
Noximilien 31:becb8f6bf7b7 179 */
Noximilien 21:0eb394495b8a 180 void updateAndDrawEnemies() {
Noximilien 21:0eb394495b8a 181 for (int i = 0; i < max_enemies; ++i) {
Noximilien 21:0eb394495b8a 182 if (enemies[i].active){
Noximilien 21:0eb394495b8a 183 enemies[i].updateAndDraw();
Noximilien 37:6a2bf4488022 184 if (!enemies[i].dead) {
Noximilien 37:6a2bf4488022 185 // Spawn blast on enemy if counter is ready
Noximilien 37:6a2bf4488022 186 enemies[i].blast_countdown -= 1;
Noximilien 37:6a2bf4488022 187 if (enemies[i].blast_countdown <= 0) {
Noximilien 37:6a2bf4488022 188 bool fired = fireEnemyBlast(enemies[i]);
Noximilien 37:6a2bf4488022 189 if (fired) {
Noximilien 37:6a2bf4488022 190 enemies[i].blast_countdown = 20;
Noximilien 37:6a2bf4488022 191 }
Noximilien 21:0eb394495b8a 192 }
Noximilien 21:0eb394495b8a 193 }
Noximilien 21:0eb394495b8a 194 }
Noximilien 21:0eb394495b8a 195 }
Noximilien 21:0eb394495b8a 196 }
Noximilien 31:becb8f6bf7b7 197
Noximilien 36:207ec7db8648 198
Noximilien 31:becb8f6bf7b7 199 /**
Noximilien 36:207ec7db8648 200 * @brief Uodates and draws all active blasts.
Noximilien 36:207ec7db8648 201 */
Noximilien 36:207ec7db8648 202 void updateAndDrawEnemyBlasts() {
Noximilien 36:207ec7db8648 203 for (int i = 0; i < max_enemy_blasts; ++i) {
Noximilien 36:207ec7db8648 204 if (enemy_blasts[i].active) {
Noximilien 36:207ec7db8648 205 enemy_blasts[i].pos.x -= enemy_blast_speed;
Noximilien 36:207ec7db8648 206 if (enemy_blasts[i].pos.x <= -1){
Noximilien 36:207ec7db8648 207 enemy_blasts[i].active = false;
Noximilien 36:207ec7db8648 208 }
Noximilien 36:207ec7db8648 209 drawSprite(enemy_blasts[i].pos, blast_sprite);
Noximilien 36:207ec7db8648 210 }
Noximilien 36:207ec7db8648 211 }
Noximilien 36:207ec7db8648 212 }
Noximilien 36:207ec7db8648 213 /**
Noximilien 36:207ec7db8648 214 * @var int blast_speed
Noximilien 36:207ec7db8648 215 * @brief ow fast should an enemy blast moves.
Noximilien 36:207ec7db8648 216 */
Noximilien 36:207ec7db8648 217 int enemy_blast_speed;
Noximilien 36:207ec7db8648 218
Noximilien 36:207ec7db8648 219 private:
Noximilien 36:207ec7db8648 220 /**
Noximilien 31:becb8f6bf7b7 221 * @brief Spawns a blast at the position of given enemy.
Noximilien 31:becb8f6bf7b7 222 * @param enemy (const Enemy&)
Noximilien 31:becb8f6bf7b7 223 */
Noximilien 21:0eb394495b8a 224 bool fireEnemyBlast(const Enemy& enemy) {
Noximilien 21:0eb394495b8a 225 int found = -1;
Noximilien 21:0eb394495b8a 226 for (int i = 0; i < max_enemy_blasts; ++i) {
Noximilien 21:0eb394495b8a 227 if (!enemy_blasts[i].active) {
Noximilien 21:0eb394495b8a 228 found = i;
Noximilien 21:0eb394495b8a 229 break;
Noximilien 21:0eb394495b8a 230 }
Noximilien 21:0eb394495b8a 231 }
Noximilien 21:0eb394495b8a 232 if (found != -1) {
Noximilien 21:0eb394495b8a 233 enemy_blasts[found].active = true;
Noximilien 21:0eb394495b8a 234 enemy_blasts[found].pos.x = enemy.pos.x;
Noximilien 21:0eb394495b8a 235 enemy_blasts[found].pos.y = enemy.pos.y + enemy2_height / 2;
Noximilien 23:240bc00ef25b 236 gamepad.tone(500,0.1);
Noximilien 21:0eb394495b8a 237 return true;
Noximilien 21:0eb394495b8a 238 }
Noximilien 21:0eb394495b8a 239 return false;
Noximilien 21:0eb394495b8a 240 }
Noximilien 21:0eb394495b8a 241 };
Noximilien 21:0eb394495b8a 242
Noximilien 21:0eb394495b8a 243 #endif