Initial publish
Dependencies: mbed
Fork of el17dg by
game/boss.h
- Committer:
- Noximilien
- Date:
- 2019-05-07
- Revision:
- 40:e3bbda7444fa
- Parent:
- 39:ca77a6d574e6
File content as of revision 40:e3bbda7444fa:
#ifndef BOSS_H #define BOSS_H #include "constants.h" /** * Boss Class * @brief A class to describe the states of the boss ship. * @author Dmitrijs Griskovs * @date 30/04/2019 */ class Boss : public GameObject { public: /** * @brief Maximum boss blasts on the screen. */ static const int max_boss_blasts = 5; GameObject boss_blasts[max_boss_blasts]; CircleBounds boss_bounds; CircleBounds boss_blast_bounds; /** * Constructor * Sets values for the boss' sprite body circle area, the blast circle * area and the circle radius for collsion callculations. Also, resets the * cutscene. */ Boss() { boss_bounds.center.x = 5; boss_bounds.center.y = 8; boss_bounds.radius = 10; boss_blast_bounds.center.x = 1; boss_blast_bounds.center.y = 0; boss_blast_bounds.radius = 1; switch_boss_y_dir = true; animation_counter = 0; resetCutscene(); } /** * @brief Updates and draws the boss blasts accross the screen. */ void updateAndDrawBossBlasts() { for (int i = 0; i < max_boss_blasts; ++i) { if (boss_blasts[i].active) { boss_blasts[i].pos.x -= boss_blast_speed; if (boss_blasts[i].pos.x <= 0){ boss_blasts[i].active = false; continue; } drawSprite(boss_blasts[i].pos, blast_sprite); } } } /** * @brief Updates and draws the boss. * @details this function is monitored in game.cpp and when the boss becomes * inactive, the gameplay would switch from boss to normal. * @returns bool active, when the boss is out of lives */ bool updateAndDrawBoss(){ if(switch_boss_y_dir) { pos.y += 1;} else { pos.y -= 1;} if (pos.y >= (game_area_height - enemy1_height)){ switch_boss_y_dir = false;} else if (pos.y <= game_area_y) { switch_boss_y_dir = true;} blast_countdown -= 1; if (blast_countdown <= 0) { fireNewBlast(pos.x, pos.y + 2); fireNewBlast(pos.x, pos.y + enemy1_height - 2); blast_countdown = 10; } if(!dead() && active){ draw();} else{ GameGlobals::game_score += 300; GameGlobals::score_count_for_boss_mode = 0; updateAndDrawDeathExplosion(); lcd.normalMode(); } return active; } /** * @brief Updates and draws the boss' cutscene of entering the game. * @details It freezes the screen until the boss is set on the screen. Also, * it sets its position and number of lives. * @returns bool active, when the boss is out of lives */ void updateCutscene() { if (!started_cutscene) { started_cutscene = true; pos.y = screen_height/2 - (enemy1_height/2); pos.x = screen_width; animation_counter = 0; active = true; boss_lives = 10; dead_counter = 5; DG_PRINTF("boss lives set to: %i \n", boss_lives); return; } if (animation_counter < animation_length) { pos.x -= 1; animation_counter++; } } /** @brief draws boss' sprite.*/ void draw() { drawSpriteOnTop(pos, enemy1_sprite);} /** @brief resets the boss' cutscene.*/ void resetCutscene() { started_cutscene = false; } /** * @returns bool true * @brief It starts the boss fight sequence when the cutscene is finished. */ bool isFinishedCutscene() { return animation_counter >= animation_length; } /** * @var int boss_lives * @brief contains boss' lives. */ int boss_lives; private: void updateAndDrawDeathExplosion() { for(int dead_counter; dead_counter >= 0; dead_counter--){ if (dead_counter > 0) { if (dead_counter == 4){ drawSpriteOnTop(pos, enemy1_quarter_exploded_sprite); } else if (dead_counter == 3){ drawSpriteOnTop(pos, enemy1_half_exploded_sprite); } else if (dead_counter == 2){ drawSpriteOnTop(pos, enemy1_second_quarter_exploded_sprite); } else if (dead_counter == 1){ drawSpriteOnTop(pos, enemy1_fully_exploded_sprite); } } else { active = false; DG_PRINTF("boss died \n"); } } } /** * @brief Spawns a blast at the position of the boss. * @param x (int x) to give x position of the boss blast. * @param y (int y) to give y position of the boss blast. * @details For this function the parameters are required to be able to spawn * two independed from each other blasts at the same time and different * positions. */ bool fireNewBlast(int x, int y) { // Search the array of blasts if inactive we can use it. int found = -1; for (int i = 0; i < max_boss_blasts; ++i) { if (!boss_blasts[i].active) { found = i; break; } } if (found != -1) { boss_blasts[found].active = true; boss_blasts[found].pos.x = x; boss_blasts[found].pos.y = y; gamepad.tone(500,0.1); return true; } return false; } static const int boss_y_speed = 2; static const int boss_blast_speed = 4; static const int animation_length = 20; bool dead(){return boss_lives == 0;} bool started_cutscene; bool switch_boss_y_dir; int blast_countdown; int animation_counter; int dead_counter; }; #endif