Initial publish

Dependencies:   mbed

Fork of el17dg by Dmitrijs Griskovs

Committer:
Noximilien
Date:
Wed Apr 10 15:42:10 2019 +0000
Revision:
28:35af3843de8f
Parent:
27:f05f4e738ba9
Child:
29:579e00b7f118
Moved starSpawnDelay to stars.h. Made enemies move y-direction as the game score increase. Added more comments. Cleaned the code a bit. Changed struct to gameObject in the main.cpp. Made some functions less than 20 lines.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Noximilien 3:10918b0f7a7d 1 #include "mbed.h"
Noximilien 3:10918b0f7a7d 2 #include "N5110.h"
Noximilien 3:10918b0f7a7d 3 #include "Gamepad.h"
Noximilien 3:10918b0f7a7d 4
Noximilien 3:10918b0f7a7d 5 #include "models.h"
Noximilien 4:02c63aaa2df9 6 #include "main.h"
Noximilien 4:02c63aaa2df9 7 #include "game.h"
Noximilien 21:0eb394495b8a 8 #include "geometry.h"
Noximilien 21:0eb394495b8a 9 #include "gameobject.h"
Noximilien 21:0eb394495b8a 10
Noximilien 21:0eb394495b8a 11 #include "enemies.h"
Noximilien 22:4dc3c95f2146 12 #include "constants.h"
Noximilien 23:240bc00ef25b 13 #include "stars.h"
Noximilien 23:240bc00ef25b 14 #include "player.h"
Noximilien 26:676874c42883 15 #include "hud.h"
Noximilien 20:557e84189a57 16
Noximilien 21:0eb394495b8a 17 bool game_over = true;
Noximilien 21:0eb394495b8a 18 int game_score;
Noximilien 28:35af3843de8f 19 int high_score = 0;
Noximilien 26:676874c42883 20 int score_count_for_difficulty;
Noximilien 27:f05f4e738ba9 21 int player_lifes = 3;
Noximilien 21:0eb394495b8a 22 bool red_led_state;
Noximilien 21:0eb394495b8a 23 int red_led_flashing;
Noximilien 26:676874c42883 24 int enemy_ship_delay_counter;
Noximilien 7:42376925945c 25
Noximilien 26:676874c42883 26 const int increase_difficulty = 50;
Noximilien 26:676874c42883 27 int enemy_ship_delay_max = 40;
Noximilien 11:cf2ba52e8b7e 28
Noximilien 21:0eb394495b8a 29 Enemies enemies;
Noximilien 23:240bc00ef25b 30 Stars stars;
Noximilien 23:240bc00ef25b 31 Player playerShip;
Noximilien 23:240bc00ef25b 32 GameObject gameOverLogo;
Noximilien 23:240bc00ef25b 33 GameObject youDied;
Noximilien 26:676874c42883 34 Hud hud;
Noximilien 12:bfe3a3deaac3 35
Noximilien 22:4dc3c95f2146 36 /**@brief
Noximilien 22:4dc3c95f2146 37 * This function checks whether the requirments for the collision of the two objects,
Noximilien 22:4dc3c95f2146 38 * are met. When those requirments are met the collision of two objects function will
Noximilien 22:4dc3c95f2146 39 * be checking wheter the boundaries of the objects colide. If they do, the blast
Noximilien 22:4dc3c95f2146 40 * becomes inactive, in game score increases and enemy dies.
Noximilien 22:4dc3c95f2146 41 */
Noximilien 21:0eb394495b8a 42 void Game::collideEnemiesAndBlasts() {
Noximilien 21:0eb394495b8a 43 for (int i = 0; i < max_enemies; ++i) {
Noximilien 23:240bc00ef25b 44 for (int j = 0; j < max_player_blasts; ++j) {
Noximilien 21:0eb394495b8a 45 Enemy& enemy = enemies.enemies[i];
Noximilien 21:0eb394495b8a 46 GameObject& blast = blasts[j];
Noximilien 21:0eb394495b8a 47 if (enemy.active && !enemy.dead && blast.active) {
Noximilien 12:bfe3a3deaac3 48 bool collision = circleCollideTwoObjects(
Noximilien 21:0eb394495b8a 49 enemy.pos, enemies.enemy_bounds,
Noximilien 21:0eb394495b8a 50 blast.pos, blast_bounds
Noximilien 12:bfe3a3deaac3 51 );
Noximilien 12:bfe3a3deaac3 52 if (collision) {
Noximilien 21:0eb394495b8a 53 enemy.die();
Noximilien 21:0eb394495b8a 54 game_score += 30;
Noximilien 26:676874c42883 55 score_count_for_difficulty +=30;
Noximilien 21:0eb394495b8a 56 blast.active = false;
Noximilien 12:bfe3a3deaac3 57 }
Noximilien 12:bfe3a3deaac3 58 }
Noximilien 12:bfe3a3deaac3 59 }
Noximilien 12:bfe3a3deaac3 60 }
Noximilien 12:bfe3a3deaac3 61 }
Noximilien 5:2b9181bc5c89 62
Noximilien 22:4dc3c95f2146 63 /**@brief
Noximilien 23:240bc00ef25b 64 * This code does the same work as the one before but with two other objects.
Noximilien 22:4dc3c95f2146 65 * It checks whether the requirments for the collision of the two objects,
Noximilien 22:4dc3c95f2146 66 * are met. When those requirments are met the collision of two objects function will
Noximilien 22:4dc3c95f2146 67 * be checking wheter the boundaries of the objects colide. If they do, the blast
Noximilien 22:4dc3c95f2146 68 * becomes inactive, in game score increases and enemy dies.
Noximilien 22:4dc3c95f2146 69 */
Noximilien 21:0eb394495b8a 70 void Game::collideEnemiesBlastsAndPlayer() {
Noximilien 23:240bc00ef25b 71 for (int i = 0; i < max_enemies; ++i) {
Noximilien 21:0eb394495b8a 72 GameObject& blast = enemies.enemy_blasts[i];
Noximilien 21:0eb394495b8a 73 if (blast.active) {
Noximilien 21:0eb394495b8a 74 bool collision = circleCollideTwoObjects(
Noximilien 21:0eb394495b8a 75 player.pos, player_bounds,
Noximilien 21:0eb394495b8a 76 blast.pos, enemies.enemy_blast_bounds
Noximilien 21:0eb394495b8a 77 );
Noximilien 21:0eb394495b8a 78 if (collision) {
Noximilien 23:240bc00ef25b 79 gamepad.tone(87,0.3);
Noximilien 23:240bc00ef25b 80 gamepad.tone(287,0.2);
Noximilien 23:240bc00ef25b 81 gamepad.tone(423,0.4);
Noximilien 27:f05f4e738ba9 82 printf("lost a life. left: %i \n", player_lifes);
Noximilien 21:0eb394495b8a 83 player_lifes -= 1;
Noximilien 21:0eb394495b8a 84 blast.active = false;
Noximilien 18:6becc9f9de5e 85 }
Noximilien 18:6becc9f9de5e 86 }
Noximilien 18:6becc9f9de5e 87 }
Noximilien 18:6becc9f9de5e 88 }
Noximilien 26:676874c42883 89
Noximilien 22:4dc3c95f2146 90 /**@brief
Noximilien 23:240bc00ef25b 91 * This code does the same work as the one before but with two other object.
Noximilien 23:240bc00ef25b 92 * of enemy ship and the player's ship
Noximilien 22:4dc3c95f2146 93 */
Noximilien 23:240bc00ef25b 94 void Game::collideEnemiesAndPlayer() {
Noximilien 27:f05f4e738ba9 95 for (int i = 0; i < max_enemies; ++i) {
Noximilien 23:240bc00ef25b 96 Enemy& enemy = enemies.enemies[i];
Noximilien 23:240bc00ef25b 97 if (enemy.active && !enemy.dead) {
Noximilien 23:240bc00ef25b 98 bool collision = circleCollideTwoObjects(
Noximilien 23:240bc00ef25b 99 player.pos, player_bounds,
Noximilien 23:240bc00ef25b 100 enemy.pos, enemies.enemy_bounds
Noximilien 23:240bc00ef25b 101 );
Noximilien 23:240bc00ef25b 102 if (collision) {
Noximilien 27:f05f4e738ba9 103 player_lifes -= 1;
Noximilien 23:240bc00ef25b 104 enemy.die();
Noximilien 23:240bc00ef25b 105 }
Noximilien 23:240bc00ef25b 106 }
Noximilien 23:240bc00ef25b 107 }
Noximilien 13:5c3dc6e827c2 108 }
Noximilien 13:5c3dc6e827c2 109
Noximilien 26:676874c42883 110 /**@brief
Noximilien 26:676874c42883 111 * This function resets all the values to their intial states when the game is
Noximilien 26:676874c42883 112 * first began when the player dies and wants to restart the game.
Noximilien 23:240bc00ef25b 113 * It does not reset the values when the game is paused.
Noximilien 23:240bc00ef25b 114 */
Noximilien 21:0eb394495b8a 115 void Game::startNewGame() {
Noximilien 23:240bc00ef25b 116 gameOverLogo.pos.x = game_area_x - 29; // 0 - the sprite length
Noximilien 23:240bc00ef25b 117 gameOverLogo.pos.y = game_area_y;
Noximilien 23:240bc00ef25b 118 youDied.pos.x = game_area_width;
Noximilien 23:240bc00ef25b 119 youDied.pos.y = game_area_y;
Noximilien 21:0eb394495b8a 120 game_over = false;
Noximilien 23:240bc00ef25b 121 player.pos.x = 0; //player was defined in player.h
Noximilien 21:0eb394495b8a 122 player.pos.y = 24;
Noximilien 26:676874c42883 123 stars_delay = 0;
Noximilien 26:676874c42883 124 enemy_ship_delay_max = 40;
Noximilien 26:676874c42883 125 enemy_ship_delay_counter = enemy_ship_delay_max;
Noximilien 21:0eb394495b8a 126 game_score = 0;
Noximilien 26:676874c42883 127 score_count_for_difficulty = 0;
Noximilien 21:0eb394495b8a 128 player_lifes = 3;
Noximilien 21:0eb394495b8a 129 red_led_state = false;
Noximilien 21:0eb394495b8a 130 red_led_flashing = 0;
Noximilien 26:676874c42883 131 enemy_blast_speed = 3;
Noximilien 26:676874c42883 132 enemy_speed = 1;
Noximilien 21:0eb394495b8a 133 for (int i = 0; i < max_enemies; ++i) {
Noximilien 21:0eb394495b8a 134 enemies.enemies[i].active = false;
Noximilien 13:5c3dc6e827c2 135 }
Noximilien 23:240bc00ef25b 136 for (int i = 0; i < max_player_blasts; ++i) {
Noximilien 21:0eb394495b8a 137 blasts[i].active = false;
Noximilien 13:5c3dc6e827c2 138 }
Noximilien 21:0eb394495b8a 139 for (int i = 0; i < max_enemy_blasts; ++i) {
Noximilien 21:0eb394495b8a 140 enemies.enemy_blasts[i].active = false;
Noximilien 13:5c3dc6e827c2 141 }
Noximilien 27:f05f4e738ba9 142 //Reset start button event
Noximilien 27:f05f4e738ba9 143 gamepad.check_event(gamepad.START_PRESSED);
Noximilien 27:f05f4e738ba9 144
Noximilien 13:5c3dc6e827c2 145 }
Noximilien 13:5c3dc6e827c2 146
Noximilien 26:676874c42883 147 /**@brief
Noximilien 23:240bc00ef25b 148 * A game over function that shows the sprites of "game over" and "you died".
Noximilien 23:240bc00ef25b 149 * Allows to reset the game to play again.
Noximilien 23:240bc00ef25b 150 */
Noximilien 23:240bc00ef25b 151 void Game::gameOver() {
Noximilien 28:35af3843de8f 152 drawGameOver();
Noximilien 26:676874c42883 153 char buffer[32];
Noximilien 24:0570cb4b92d7 154 sprintf(buffer,"Your Score %i",game_score);
Noximilien 24:0570cb4b92d7 155 lcd.printString(buffer,0,3);
Noximilien 23:240bc00ef25b 156 wait(1);
Noximilien 23:240bc00ef25b 157 lcd.printString("Press Y",0,4);
Noximilien 23:240bc00ef25b 158 lcd.printString("to restart",0,5);
Noximilien 23:240bc00ef25b 159 lcd.refresh();
Noximilien 23:240bc00ef25b 160 bool led_state = false;
Noximilien 23:240bc00ef25b 161 while (!gamepad.check_event(gamepad.Y_PRESSED)){//////////////////////////////
Noximilien 23:240bc00ef25b 162 gamepad.led(1,(float)led_state);
Noximilien 23:240bc00ef25b 163 gamepad.led(2,(float)!led_state);
Noximilien 23:240bc00ef25b 164 gamepad.led(3,(float)led_state);
Noximilien 23:240bc00ef25b 165 gamepad.led(4,(float)!led_state);
Noximilien 23:240bc00ef25b 166 gamepad.led(5,(float)led_state);
Noximilien 23:240bc00ef25b 167 gamepad.led(6,(float)!led_state);
Noximilien 23:240bc00ef25b 168 wait(0.5);
Noximilien 23:240bc00ef25b 169 led_state = !led_state;
Noximilien 23:240bc00ef25b 170 }
Noximilien 23:240bc00ef25b 171 }
Noximilien 23:240bc00ef25b 172
Noximilien 26:676874c42883 173 /**@brief
Noximilien 26:676874c42883 174 * A function tbat delays enemy spawn on low game score.
Noximilien 26:676874c42883 175 * It decreases the enemy spawn delay as in game score increases.
Noximilien 26:676874c42883 176 */
Noximilien 26:676874c42883 177 void Game::increaseGameDifficultyAndEnemySpawnDelay(){
Noximilien 26:676874c42883 178 if (enemy_ship_delay_counter <= 0){
Noximilien 26:676874c42883 179 enemies.spawnNewEnemy();
Noximilien 26:676874c42883 180 enemy_ship_delay_counter = enemy_ship_delay_max;
Noximilien 26:676874c42883 181 }
Noximilien 26:676874c42883 182 else { enemy_ship_delay_counter -= 1;}
Noximilien 26:676874c42883 183
Noximilien 26:676874c42883 184 if (enemy_ship_delay_max >= 4 && score_count_for_difficulty >= increase_difficulty){
Noximilien 26:676874c42883 185 enemy_ship_delay_max -= 3;
Noximilien 26:676874c42883 186
Noximilien 26:676874c42883 187 if (enemy_ship_delay_max <= 20 && enemy_ship_delay_max >= 15){
Noximilien 26:676874c42883 188 enemy_blast_speed += 1;
Noximilien 26:676874c42883 189 enemy_speed += 1;
Noximilien 26:676874c42883 190 }
Noximilien 26:676874c42883 191 score_count_for_difficulty = 0;
Noximilien 26:676874c42883 192 }
Noximilien 26:676874c42883 193 }
Noximilien 26:676874c42883 194
Noximilien 26:676874c42883 195 /**@brief
Noximilien 23:240bc00ef25b 196 * This is the main function of game.cpp, where the actual gameplay happens.
Noximilien 23:240bc00ef25b 197 * Here all other functions are activeated, and when the player dies, it
Noximilien 23:240bc00ef25b 198 * returns back to main menu "main.cpp".
Noximilien 23:240bc00ef25b 199 */
Noximilien 21:0eb394495b8a 200 bool Game::updateAndDraw() {
Noximilien 27:f05f4e738ba9 201 //printf("update \n");
Noximilien 21:0eb394495b8a 202 if (game_over) {
Noximilien 27:f05f4e738ba9 203 printf("start game \n");
Noximilien 21:0eb394495b8a 204 startNewGame();
Noximilien 13:5c3dc6e827c2 205 }
Noximilien 26:676874c42883 206
Noximilien 19:b78fa41d04a9 207 if (gamepad.check_event(gamepad.X_PRESSED)){
Noximilien 28:35af3843de8f 208 // Checking the button second time to prevent double blast.
Noximilien 28:35af3843de8f 209 gamepad.check_event(gamepad.X_PRESSED);
Noximilien 23:240bc00ef25b 210 playerShip.fireNewBlast();
Noximilien 23:240bc00ef25b 211 gamepad.tone(200,0.1);
Noximilien 6:100b46be4bea 212 }
Noximilien 26:676874c42883 213
Noximilien 26:676874c42883 214 playerShip.playerShipMovement();
Noximilien 28:35af3843de8f 215 stars.starsSpawnDelay();
Noximilien 26:676874c42883 216 increaseGameDifficultyAndEnemySpawnDelay();
Noximilien 26:676874c42883 217 hud.displayLifes();
Noximilien 23:240bc00ef25b 218 playerShip.updateAndDrawBlasts();
Noximilien 23:240bc00ef25b 219 stars.updateAndDrawSmallStars();
Noximilien 23:240bc00ef25b 220 stars.updateAndDrawMediumStars();
Noximilien 21:0eb394495b8a 221 enemies.updateAndDrawEnemies();
Noximilien 12:bfe3a3deaac3 222 collideEnemiesAndBlasts();
Noximilien 18:6becc9f9de5e 223 collideEnemiesBlastsAndPlayer();
Noximilien 23:240bc00ef25b 224 collideEnemiesAndPlayer();
Noximilien 21:0eb394495b8a 225 enemies.updateAndDrawEnemyBlasts();
Noximilien 27:f05f4e738ba9 226 hud.drawScore();
Noximilien 24:0570cb4b92d7 227
Noximilien 24:0570cb4b92d7 228 /**@brief
Noximilien 26:676874c42883 229 * This small statment checks whether the pause button was pressed or not.
Noximilien 26:676874c42883 230 * If it was pressed, then the game will go back to main menu and will save
Noximilien 26:676874c42883 231 * the current status of the object until the game is continued.
Noximilien 26:676874c42883 232 */
Noximilien 4:02c63aaa2df9 233 bool want_to_pause = false;
Noximilien 27:f05f4e738ba9 234 game_over = checkForGameOver();
Noximilien 21:0eb394495b8a 235 if (game_over){
Noximilien 27:f05f4e738ba9 236 printf("game over happened\n");
Noximilien 23:240bc00ef25b 237 gameOver();
Noximilien 21:0eb394495b8a 238 want_to_pause = true;
Noximilien 21:0eb394495b8a 239 }
Noximilien 4:02c63aaa2df9 240 if (gamepad.check_event(gamepad.START_PRESSED)){
Noximilien 27:f05f4e738ba9 241 printf("pausing the game\n");
Noximilien 28:35af3843de8f 242 gamepad.check_event(gamepad.START_PRESSED);
Noximilien 19:b78fa41d04a9 243 want_to_pause = true;
Noximilien 4:02c63aaa2df9 244 }
Noximilien 4:02c63aaa2df9 245 return want_to_pause;
Noximilien 27:f05f4e738ba9 246 }
Noximilien 27:f05f4e738ba9 247 /**@brief
Noximilien 27:f05f4e738ba9 248 * This is a single line function to set the player lifes to 0 when the.
Noximilien 27:f05f4e738ba9 249 * game is over.
Noximilien 27:f05f4e738ba9 250 */
Noximilien 27:f05f4e738ba9 251 bool Game::checkForGameOver() {
Noximilien 27:f05f4e738ba9 252 return player_lifes == 0;
Noximilien 28:35af3843de8f 253 }
Noximilien 28:35af3843de8f 254 void Game::drawGameOver(){
Noximilien 28:35af3843de8f 255 for (int i = 0; i < 42; i++){
Noximilien 28:35af3843de8f 256 lcd.clear();
Noximilien 28:35af3843de8f 257 lcd.drawSprite(gameOverLogo.pos.x + i, gameOverLogo.pos.y, 14, 29, (int*)gameOverSprite);
Noximilien 28:35af3843de8f 258 lcd.drawSprite(youDied.pos.x - i, youDied.pos.y, 14, 24, (int*)youDiedSprite);
Noximilien 28:35af3843de8f 259 lcd.refresh();
Noximilien 28:35af3843de8f 260 wait(0.1);
Noximilien 28:35af3843de8f 261 }
Noximilien 26:676874c42883 262 }