A rouge-like rpg, heavily inspired on the binding of isaac. Running on a FRDM-K64F Mbed board. C++.
Dependencies: mbed MotionSensor
main.cpp
00001 /* 00002 ELEC2645 Embedded Systems Project 00003 School of Electronic & Electrical Engineering 00004 University of Leeds 00005 Name: Steven Mahasin 00006 Username: el17sm 00007 Student ID Number: 201192939 00008 Date: 11/04/2019 00009 */ 00010 #include "main.h" 00011 00012 int main() 00013 { 00014 // Initialize 00015 init(); 00016 00017 while(1) { // Gameloop 00018 boss_room_exist = false; // Game initialize variables 00019 number_of_enemies_killed = 0; 00020 total_time = 0; 00021 00022 title.main(lcd, gamepad, global_contrast); 00023 srand(title.get_seed()); 00024 player = new Player(39, 27); 00025 room_engine = new RoomEngine(global_contrast); 00026 00027 game_loop(); 00028 game_unload(); // Deletion of player, rooms, roomengine 00029 } 00030 } 00031 00032 void init() 00033 { 00034 lcd.init(); 00035 lcd.setContrast(global_contrast); 00036 gamepad.init(); 00037 for (int j = 0; j < MAX_ROOMS_MAP_Y; j++){ 00038 for (int i = 0; i < MAX_ROOMS_MAP_X; i++){ 00039 valid_rooms[j][i] = false; 00040 } 00041 } 00042 } 00043 00044 void game_loop() 00045 { 00046 while(1) { // Floor Loop 00047 boss_room_number = 5 + rand() % 4; // Boss room appears after travelling 5-8 rooms 00048 boss_room_counter = 0; 00049 while(1) { // Room Loop 00050 room_entrance(); // Generation of new room, loading of room and entrance scene 00051 while(room_engine->check_player_room_position() == INSIDE) { // actions inside the Room 00052 room_engine->read_input(gamepad); 00053 room_engine->update(number_of_enemies_killed); 00054 room_engine->render(lcd, gamepad); 00055 minimap_detection(); 00056 total_time++; // Incrementing time score 00057 if (player->get_hp() <= 0) {goto gameover;} // gameover if player health depleted 00058 if ((rooms[room_y][room_x]->get_room_type() == 10) && !(rooms[room_y][room_x]->enemies_exist())){goto winner;} // wins game if room is a boss room, and the boss is dead 00059 } 00060 room_exit(); // Exit scene, deletion of existing entities and update of room coordinates 00061 } 00062 } 00063 gameover : { game_over(); goto displaystats;} 00064 winner : { win(); goto displaystats;} 00065 displaystats : { display_stats();} 00066 } 00067 00068 void room_entrance() 00069 { 00070 update_room_coords(); // Accessor to room_engine room coords 00071 if (!valid_rooms[room_y][room_x]){generate_room();} // generate a new room if player enters a nonexistent room 00072 room_engine->load(player, rooms[room_y][room_x]); 00073 room_engine->entrance_scene(lcd, gamepad); 00074 } 00075 00076 void room_exit() 00077 { 00078 room_engine->exit_scene(lcd, gamepad); 00079 rooms[room_y][room_x]->unload(); 00080 player->delete_bullets(); 00081 room_engine->update_current_room(); // Increments room coord 00082 } 00083 00084 void generate_room() 00085 { 00086 valid_rooms[room_y][room_x] = true; // Sets the room coord to be valid 00087 if (boss_room_counter == 0) { // if first room 00088 rooms[room_y][room_x] = new Room(0, 0); // no enemies 00089 rooms[room_y][room_x]->set_doorway(0, true); 00090 } else { 00091 rooms[room_y][room_x] = new Room(rand() % 4, 0); // random enemies (0-3) 00092 if (boss_room_counter < boss_room_number) {no_of_doorways = 2 + (rand() % 100 < 10) + (rand() % 100 < 10);} // 20% chance of adding doorways 00093 else {no_of_doorways = 1;} // If boss room exist, ensure all unexplored rooms branch out into a dead end 00094 while (count_doorways() < no_of_doorways) { 00095 rooms[room_y][room_x]->set_doorway(rand() % 4, true); // Setting random doorways until number of desired doorways 00096 } 00097 update_definite_doorways(); 00098 for (int i = 0; i < 4; i++) { // Sets the definitive doorways 00099 if (cannot[i]){rooms[room_y][room_x]->set_doorway(i, false);} 00100 if (have_to[i]){rooms[room_y][room_x]->set_doorway(i, true);} 00101 } 00102 if ((boss_room_counter >= boss_room_number) && (!boss_room_exist)) { // Sets the doorway towards the boss room to be a boss doorway 00103 rooms[room_y][room_x]->set_boss_doorway(available_boss_room()); 00104 boss_room_exist = true; 00105 } 00106 } 00107 boss_room_counter++; 00108 } 00109 00110 void update_room_coords() 00111 { 00112 room_y = room_engine->get_room_y(); 00113 room_x = room_engine->get_room_x(); 00114 } 00115 00116 void minimap_detection() 00117 { 00118 while(gamepad.check_event(Gamepad::R_PRESSED)) { 00119 lcd.clear(); 00120 for (int j = 0; j < MAX_ROOMS_MAP_Y; j++) { 00121 for (int i = 0; i < MAX_ROOMS_MAP_X; i++) { 00122 if (valid_rooms[j][i]) { 00123 draw_minimap(j,i); 00124 } 00125 } 00126 } 00127 lcd.drawSpriteTransparent(33, 17, 15, 20, (char *)minimap_sprite[3]); // draws your current room 00128 lcd.refresh(); 00129 wait_ms(1000/40); 00130 }; 00131 } 00132 00133 void draw_minimap(int j, int i) 00134 { 00135 lcd.drawSprite(33 + (i-room_x)*20, 17 + (j-room_y)*15, 15, 20, (char *)minimap_sprite[0]); // draws normal room 00136 if (rooms[j][i]->get_room_type() == 10) { 00137 lcd.drawSprite(33 + (i-room_x)*20, 17 + (j-room_y)*15, 15, 20, (char *)minimap_sprite[2]); // draws boss room 00138 } else if (rooms[j][i]->enemies_exist()) { 00139 lcd.drawSprite(33 + (i-room_x)*20, 17 + (j-room_y)*15, 15, 20, (char *)minimap_sprite[1]); // draws mob room 00140 } 00141 if (rooms[j][i]->get_doorway(0)) { // Drawing all doorways 00142 lcd.drawLine(42 + (i-room_x)*20, 17 + (j-room_y)*15, 43 + (i-room_x)*20, 17 + (j-room_y)*15, 1); 00143 } 00144 if (rooms[j][i]->get_doorway(1)) { 00145 lcd.drawLine(52 + (i-room_x)*20, 23 + (j-room_y)*15, 52 + (i-room_x)*20, 24 + (j-room_y)*15, 1); 00146 } 00147 if (rooms[j][i]->get_doorway(2)) { 00148 lcd.drawLine(42 + (i-room_x)*20, 31 + (j-room_y)*15, 43 + (i-room_x)*20, 31 + (j-room_y)*15, 1); 00149 } 00150 if (rooms[j][i]->get_doorway(3)) { 00151 lcd.drawLine(33 + (i-room_x)*20, 23 + (j-room_y)*15, 33 + (i-room_x)*20, 24 + (j-room_y)*15, 1); 00152 } 00153 } 00154 00155 void game_over() 00156 { 00157 lcd.clear(); 00158 lcd.setContrast(global_contrast); 00159 lcd.printString("Game Over", 0, 0); 00160 } 00161 00162 void win() 00163 { 00164 lcd.clear(); 00165 lcd.setContrast(global_contrast); 00166 lcd.printString("You won!", 0, 0); 00167 } 00168 00169 void display_stats() 00170 { 00171 lcd.printString("Restart?", 0, 1); 00172 lcd.printString("Enemies Killed:", 0, 2); 00173 char kills[10]; 00174 sprintf(kills, "%d enemies", number_of_enemies_killed); 00175 lcd.printString(kills, 0, 3); 00176 lcd.printString("Time:", 0, 4); 00177 char total_duration[10]; 00178 sprintf(total_duration, "%d seconds", (total_time/40)); 00179 lcd.printString(total_duration, 0, 5); 00180 lcd.refresh(); 00181 while(gamepad.check_event(Gamepad::A_PRESSED)) { 00182 } 00183 wait(0.05); 00184 while(!gamepad.check_event(Gamepad::A_PRESSED)) { 00185 } 00186 wait(0.05); 00187 while(gamepad.check_event(Gamepad::A_PRESSED)) { 00188 } 00189 } 00190 00191 int available_boss_room() 00192 { 00193 if (!valid_rooms[room_y - 1][room_x]){ // if any of the adjacent room is invalid, it is replaced with a boss room 00194 rooms[room_y][room_x]->set_doorway(0, true); 00195 set_boss_room(room_y - 1, room_x, 0); 00196 return 0; 00197 } else if (!valid_rooms[room_y][room_x + 1]){ 00198 rooms[room_y][room_x]->set_doorway(1, true); 00199 set_boss_room(room_y, room_x + 1, 1); 00200 return 1; 00201 } else if (!valid_rooms[room_y + 1][room_x]){ 00202 rooms[room_y][room_x]->set_doorway(2, true); 00203 set_boss_room(room_y + 1, room_x, 2); 00204 return 2; 00205 } else if (!valid_rooms[room_y][room_x - 1]){ 00206 rooms[room_y][room_x]->set_doorway(3, true); 00207 set_boss_room(room_y, room_x - 1, 3); 00208 return 3; } 00209 delete rooms[room_y - 1][room_x]; // if all adjacent room is valid, mutate the top room into a boss room (default case) 00210 rooms[room_y][room_x]->set_doorway(3, true); 00211 set_boss_room(room_y - 1, room_x, 0); 00212 return 0; 00213 } 00214 00215 void set_boss_room(int room_y, int room_x, int side) 00216 { 00217 valid_rooms[room_y][room_x] = true; 00218 rooms[room_y][room_x] = new Room(0, 10); 00219 rooms[room_y][room_x]->set_doorway(opposite(side), true); // Sets a definite doorway on the side player comes from 00220 if ((opposite(side) != 0) && (valid_rooms[room_y - 1][room_x])){ // Deletes any existing doorways unless player entered from that side 00221 if (rooms[room_y - 1][room_x]->get_doorway(2)){ 00222 rooms[room_y - 1][room_x]->set_doorway(2, false); 00223 }} 00224 if ((opposite(side) != 1) && (valid_rooms[room_y][room_x + 1])){ 00225 if (rooms[room_y][room_x + 1]->get_doorway(3)){ 00226 rooms[room_y][room_x + 1]->set_doorway(3, false); 00227 }} 00228 if ((opposite(side) != 2) && (valid_rooms[room_y + 1][room_x])){ 00229 if (rooms[room_y + 1][room_x]->get_doorway(0)){ 00230 rooms[room_y + 1][room_x]->set_doorway(0, false); 00231 }} 00232 if ((opposite(side) != 3) && (valid_rooms[room_y][room_x - 1])){ 00233 if (rooms[room_y][room_x - 1]->get_doorway(1)){ 00234 rooms[room_y][room_x - 1]->set_doorway(1, false); 00235 }} 00236 } 00237 00238 void game_unload() 00239 { 00240 delete room_engine; 00241 // Deletes every generated rooms 00242 for (int i = 0; i < MAX_ROOMS_MAP_X; i++) { 00243 for (int j = 0; j < MAX_ROOMS_MAP_Y; j++) { 00244 if (valid_rooms[j][i]){ 00245 delete rooms[j][i]; 00246 valid_rooms[j][i] = false; 00247 } 00248 } 00249 } 00250 delete player; 00251 } 00252 00253 // Functions 00254 int opposite(int value) 00255 { 00256 if (value <= 1) { 00257 return value + 2; 00258 } else { 00259 return value - 2; 00260 } 00261 } 00262 00263 int count_doorways() // counts number of exisisting doorways 00264 { 00265 int count = 0; 00266 for (int i = 0; i < 4; i++){ 00267 if (rooms[room_y][room_x]->get_doorway(i)) { 00268 count++; 00269 } 00270 } 00271 return count; 00272 } 00273 00274 void update_definite_doorways() 00275 { 00276 update_definite_doorways_up(); 00277 update_definite_doorways_right(); 00278 update_definite_doorways_down(); 00279 update_definite_doorways_left(); 00280 } 00281 00282 void update_definite_doorways_up() 00283 { 00284 if (room_y == 1) { // if room to be generated is on the border, then doorway cannot exist 00285 cannot[0] = true; 00286 have_to[0] = false; 00287 } else if (valid_rooms[room_y - 1][room_x]){ // if room to be generated has an existing room above it 00288 if (rooms[room_y - 1][room_x]->get_doorway(2)){ // if room to be generated has an existing doorway, then doorway must exist 00289 have_to[0] = true; 00290 cannot[0] = false; 00291 } else { // if room to be generated does not have an existing doorway, then doorway must not exist 00292 have_to[0] = false; 00293 cannot[0] = true; 00294 } 00295 } else { // else the room does not have any definite doorways set on it's north 00296 have_to[0] = false; 00297 cannot[0] = false; 00298 } 00299 } 00300 void update_definite_doorways_right() 00301 { 00302 if (room_x == 10) { // if room to be generated is on the border, then doorway cannot exist 00303 cannot[1] = true; 00304 have_to[1] = false; 00305 } else if (valid_rooms[room_y][room_x + 1]){ // if room to be generated has an existing room on it's right 00306 if (rooms[room_y][room_x + 1]->get_doorway(3)){ // if room to be generated has an existing doorway, then doorway must exist 00307 have_to[1] = true; 00308 cannot[1] = false; 00309 } else { // if room to be generated does not have an existing doorway, then doorway must not exist 00310 have_to[1] = false; 00311 cannot[1] = true; 00312 } 00313 } else { // else the room does not have any definite doorways set on it's right 00314 have_to[1] = false; 00315 cannot[1] = false; 00316 } 00317 } 00318 00319 void update_definite_doorways_down() 00320 { 00321 if (room_y == 10) { // if room to be generated is on the border, then doorway cannot exist 00322 cannot[2] = true; 00323 have_to[2] = false; 00324 } else if (valid_rooms[room_y + 1][room_x]){ // if room to be generated has an existing room below it 00325 if (rooms[room_y + 1][room_x]->get_doorway(0)){ // if room to be generated has an existing doorway, then doorway must exist 00326 have_to[2] = true; 00327 cannot[2] = false; 00328 } else { // if room to be generated does not have an existing doorway, then doorway must not exist 00329 have_to[2] = false; 00330 cannot[2] = true; 00331 } 00332 } else { // else the room does not have any definite doorways set on it's south 00333 have_to[2] = false; 00334 cannot[2] = false; 00335 } 00336 } 00337 00338 void update_definite_doorways_left() 00339 { 00340 if (room_x == 1) { // if room to be generated is on the border, then doorway cannot exist 00341 cannot[3] = true; 00342 have_to[3] = false; 00343 } else if (valid_rooms[room_y][room_x - 1]){ // if room to be generated has an existing room on it's left 00344 if (rooms[room_y][room_x - 1]->get_doorway(1)){ // if room to be generated has an existing doorway, then doorway must exist 00345 have_to[3] = true; 00346 cannot[3] = false; 00347 } else { // if room to be generated does not have an existing doorway, then doorway must not exist 00348 have_to[3] = false; 00349 cannot[3] = true; 00350 } 00351 } else { // else the room does not have any definite doorways set on it's left 00352 have_to[3] = false; 00353 cannot[3] = false; 00354 } 00355 }
Generated on Tue Jul 19 2022 23:32:07 by 1.7.2