A rouge-like rpg, heavily inspired on the binding of isaac. Running on a FRDM-K64F Mbed board. C++.

Dependencies:   mbed MotionSensor

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Room.cpp Source File

Room.cpp

00001 #include "Room.h"
00002 
00003 // Constructor
00004 Room::Room(int no_of_enemies, int room_type)
00005 {
00006     _before_boss_room = 4;
00007     
00008     _room_type = room_type;
00009     
00010     for(int side = 0; side < 4; side++) {
00011         _doorways[side] = false;
00012     }
00013     for(int id = 0; id < MAX_ENEMIES; id++) {
00014         valid_collectibles[id] = false;
00015     }
00016     
00017     if(room_type >= 10) {   // Special Case for Boss rooms
00018         init_boss_room();
00019     } else {
00020         for (int id = 0; id < MAX_ENEMIES; id++) {
00021             valid_enemies[id] = id < no_of_enemies;
00022             if (id < no_of_enemies) {   // For every undefined valid enemy, define:
00023                 enemies_type[id] = (int)(rand() % 3)/2; // 2/3 chance headless 1/3 chance snake
00024                 rand_enemy_coordinate(id);  // define random spawn coordinate
00025             }
00026         }
00027         if (room_type == 0){
00028             init_normal_room();
00029         } else if (room_type == 1){
00030             init_middle_walled_room();
00031         } else if (room_type == 2){
00032             init_side_walled_room();
00033         }
00034     }
00035 }
00036 
00037 void Room::init_boss_room()
00038 {
00039     valid_walls[0] = false;
00040     valid_walls[1] = false;
00041     valid_enemies[0] = true;
00042     for (int id = 1; id < MAX_ENEMIES; id++) {  // Updating valid_enemies to be false for all the others
00043         valid_enemies[id] = false;
00044     }
00045 }
00046 
00047 void Room::init_normal_room()
00048 {
00049     valid_walls[0] = false;
00050     valid_walls[1] = false;
00051 }
00052 
00053 void Room::init_middle_walled_room()
00054 {
00055     valid_walls[0] = true;
00056     _wall_stat[0][0] = 14;
00057     _wall_stat[0][1] = 22;
00058     _wall_stat[0][2] = 56;
00059     _wall_stat[0][3] = 12;
00060     
00061     valid_walls[1] = false;
00062 }
00063 
00064 void Room::init_side_walled_room()
00065 {
00066     valid_walls[0] = true;
00067     _wall_stat[0][0] = 16;
00068     _wall_stat[0][1] = 18;
00069     _wall_stat[0][2] = 7;
00070     _wall_stat[0][3] = 19;
00071     
00072     valid_walls[1] = true;
00073     _wall_stat[1][0] = 61;
00074     _wall_stat[1][1] = 18;
00075     _wall_stat[1][2] = 7;
00076     _wall_stat[1][3] = 19;
00077 }
00078 
00079 // Deconstructor
00080 Room::~Room()
00081 {
00082     
00083 }
00084 
00085 // Mutator
00086 void Room::set_doorway(int index, bool doorway_value)   // Sets doorways to the needed value at index
00087 {
00088     _doorways[index] = doorway_value;
00089 }
00090 
00091 void Room::set_boss_doorway(int before_boss_room)   // Sets the boss doorway
00092 {
00093     _before_boss_room = before_boss_room;
00094 }
00095 
00096 // Accessors
00097 char * Room::get_current_map_2d(){
00098     return ((char *)level_map[0][0]);
00099 }
00100 
00101 bool * Room::get_doorways()
00102 {
00103     return (bool *)_doorways;
00104 }
00105 
00106 bool Room::get_doorway(int index)
00107 {
00108     return _doorways[index];
00109 }
00110 
00111 char Room::get_room_type()
00112 {
00113     return _room_type;
00114 }
00115 
00116 int Room::get_boss_doorway()
00117 {
00118     return _before_boss_room;
00119 }
00120 
00121 // Functions
00122 void Room::rand_enemy_coordinate(int id)
00123 {
00124     _spawn_point_coord = rand() % n_spawn_points[_room_type];   // Random available spawning coordinate ID
00125     _spawn_point_counter = 0;
00126     for(int i = 0; i < WIDTH; i++) {
00127         for(int j = 0; j < HEIGHT; j++) {
00128             if(spawn_area[_room_type][j][i] == 0){  // Locate available spawning coordinate
00129                 _spawn_point_counter++; // Increment counter ID
00130             }
00131             if(_spawn_point_counter >= _spawn_point_coord){ // If counter ID  reaches the random coordinate ID
00132                 _enemy_coord[id][0] = i;    // Set the random coordinate
00133                 _enemy_coord[id][1] = j;
00134                 goto enemy_coord_set;
00135             }
00136         }
00137     }
00138     enemy_coord_set:{}  // Acts as a break since there are two for loops
00139 }
00140 
00141 void Room::load()   // Spawns all Mobs and Walls with reset status (HP, Attack etc) given that they have not died yet (still valid)
00142 {
00143     if(_room_type == 10) {
00144         if (valid_enemies[0]) {
00145             enemies[0] = new Skull(33, 23);
00146         }
00147     } else {
00148         for (int id = 0; id < MAX_ENEMIES; id++) {
00149             if (valid_enemies[id]) {
00150                 switch(enemies_type[id]){
00151                     case 0 :
00152                         enemies[id] = new Headless(_enemy_coord[id][0], _enemy_coord[id][1]); break;
00153                     case 1 :
00154                         enemies[id] = new Snake(_enemy_coord[id][0], _enemy_coord[id][1]); break;
00155                 }
00156             }
00157         }
00158         for (int id = 0; id < 2; id++) {
00159             if (valid_walls[id]) {
00160                 walls[id] = new Walls(_wall_stat[id][0], _wall_stat[id][1], _wall_stat[id][2], _wall_stat[id][3]);
00161             }
00162         }
00163     }
00164 }
00165 
00166 void Room::unload() // Delete existing enemies and walls
00167 {
00168     for (int i = 0; i < MAX_ENEMIES; i++) {
00169         if (valid_enemies[i]) {
00170             delete enemies[i];
00171         }
00172     }
00173     for (int i = 0; i < 2; i++){
00174         if (valid_walls[i]) {
00175             delete walls[i];
00176         }
00177     }
00178 }
00179 
00180 void Room::update_doorways()    // If it's a boss, close the doorways, else, 
00181 {
00182     if(_room_type == 10) { 
00183         _doorways[0] = false;
00184         _doorways[1] = false;
00185         _doorways[2] = false;
00186         _doorways[3] = false;
00187     }
00188 }
00189 
00190 void Room::draw(N5110 &lcd, int j)
00191 {
00192     draw_enemies(lcd, j);
00193     draw_collectibles(lcd, j);
00194     draw_walls(lcd, j);
00195 }
00196 
00197 void Room::draw_enemies(N5110 &lcd, int j)
00198 {
00199     for (int i = 0; i < MAX_ENEMIES; i++) {
00200         if (valid_enemies[i]) {
00201             if (enemies[i]->get_pos_y() == j) {
00202                 enemies[i]->draw(lcd);
00203             }
00204         }
00205     }
00206 }
00207 
00208 void Room::draw_collectibles(N5110 &lcd, int j)
00209 {
00210     for (int i = 0; i < MAX_ENEMIES; i++) {
00211         if (valid_collectibles[i]) {
00212             if (collectibles[i]->get_pos_y() == j) {
00213                 collectibles[i]->draw(lcd);
00214             }
00215         }
00216     }
00217 }
00218 
00219 void Room::draw_walls(N5110 &lcd, int j)
00220 {
00221     for (int i = 0; i < 2; i++) {
00222         if (valid_walls[i]) {
00223             if (walls[i]->get_pos_y() == j) {
00224                 walls[i]->draw(lcd);
00225             }
00226         }
00227     }
00228 }
00229 void Room::draw_room(N5110 &lcd)
00230 {
00231     lcd.drawSprite(0, 0, screen_height, screen_width, (char *)level_map[1]); // drawing 3d map
00232     draw_doorways(lcd); // Draw walls that are behind the player
00233     if (_before_boss_room == 0) {    // Displaying Special Doorway to Boss room
00234         lcd.drawSprite(35, 0, 12, 14, (char *)boss_doorway_n[0]);
00235     }
00236 }
00237 
00238 void Room::draw_doorways(N5110 &lcd)
00239 {
00240     if(!_doorways[0]) { // N
00241         lcd.drawSprite(36, 0, 10, 12, (char *)wall_n);
00242     }
00243 }
00244 
00245 void Room::draw_room_overlay(N5110 &lcd)
00246 {
00247     lcd.drawSpriteTransparent(0, 0, screen_height, screen_width, (char *)level_map[2]); // drawing 3d map overlay
00248     draw_doorways_overlay(lcd);
00249     if (_before_boss_room == 0) {    // Displaying Special Doorway to Boss room
00250         lcd.drawSpriteTransparent(35, 0, 12, 14, (char *)boss_doorway_n[1]);
00251     } else if (_before_boss_room == 1) {
00252         lcd.drawSpriteTransparent(79, 14, 19, 5, (char *)boss_doorway_e);
00253     } else if (_before_boss_room == 2) {
00254         lcd.drawSpriteTransparent(35, 41, 7, 14, (char *)boss_doorway_s);
00255     } else if (_before_boss_room == 3) {
00256         lcd.drawSpriteTransparent(0, 14, 19, 5, (char *)boss_doorway_w);
00257     }
00258 }
00259 
00260 void Room::draw_doorways_overlay(N5110 &lcd)    // Draw walls that are in front of the player
00261 {
00262     if(!_doorways[1]) { // E
00263         lcd.drawSpriteTransparent(81, 15, 11, 3, (char *)wall_x[0]);
00264     }
00265     if(!_doorways[2]) { // S
00266         lcd.drawSpriteTransparent(36, 45, 3, 12, (char *)wall_s);
00267     }
00268     if(!_doorways[3]) { // W
00269         lcd.drawSpriteTransparent(0, 15, 11, 3, (char *)wall_x[1]);
00270     }
00271 }
00272 
00273 bool Room::enemies_exist()  // Returns true if valid enemies exist
00274 {
00275     for (int i = 0; i < MAX_ENEMIES; i++) {
00276         if (valid_enemies[i]) {
00277             return true;
00278         }       
00279     }
00280     return false;
00281 }