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

Dependencies:   mbed MotionSensor

Committer:
el17sm
Date:
Thu May 09 08:18:36 2019 +0000
Revision:
55:fc618f82d1d0
Parent:
50:2c5cb92a5361
Child:
58:c8d90bb7404a
Bullets collision fixed

Who changed what in which revision?

UserRevisionLine numberNew contents of line
el17sm 26:abbc19edc5c1 1 #include "RoomEngine.h"
el17sm 32:fe6359ef9916 2 // Constructor
el17sm 41:0697508a28ba 3 RoomEngine::RoomEngine(float global_contrast)
el17sm 26:abbc19edc5c1 4 {
el17sm 46:f09711580d4a 5 _room_x = MAX_ROOMS_MAP_X / 2;
el17sm 46:f09711580d4a 6 _room_y = MAX_ROOMS_MAP_Y / 2;
el17sm 30:ec915d24d3e9 7 _global_contrast = global_contrast;
el17sm 26:abbc19edc5c1 8 }
el17sm 26:abbc19edc5c1 9
el17sm 32:fe6359ef9916 10 // Destructor
el17sm 27:a1b41626f57c 11 RoomEngine::~RoomEngine()
el17sm 27:a1b41626f57c 12 {
el17sm 40:cbcbf6fc1421 13 room->unload();
el17sm 27:a1b41626f57c 14 }
el17sm 27:a1b41626f57c 15
el17sm 32:fe6359ef9916 16 // Public Functions
el17sm 31:ab24d028ddfd 17 void RoomEngine::load(Player *current_player, Room *current_room)
el17sm 28:98848e6a77a2 18 {
el17sm 31:ab24d028ddfd 19 player = current_player;
el17sm 29:6b8411bb040a 20 room = current_room;
el17sm 50:2c5cb92a5361 21 set_input(true,0,0,0,0,0,0,0); // Displays health throughout entrance_scene
el17sm 50:2c5cb92a5361 22 update_player_position(check_player_room_position()); // Moving the player such that he enters opposite of his exit
el17sm 46:f09711580d4a 23 room->load();
el17sm 28:98848e6a77a2 24 }
el17sm 28:98848e6a77a2 25
el17sm 50:2c5cb92a5361 26 void RoomEngine::update_player_position(int side)
el17sm 50:2c5cb92a5361 27 {
el17sm 50:2c5cb92a5361 28 switch(side) { // Depending on which side it exits from, player is repositioned
el17sm 50:2c5cb92a5361 29 case 0 : // N
el17sm 50:2c5cb92a5361 30 player->set_position(39, 49);
el17sm 50:2c5cb92a5361 31 break;
el17sm 50:2c5cb92a5361 32 case 1 : // E
el17sm 50:2c5cb92a5361 33 player->set_position(0 - player->get_hitbox_width(), 25);
el17sm 50:2c5cb92a5361 34 break;
el17sm 50:2c5cb92a5361 35 case 2 : // S
el17sm 50:2c5cb92a5361 36 player->set_position(39, 0 - player->get_hitbox_height());
el17sm 50:2c5cb92a5361 37 break;
el17sm 50:2c5cb92a5361 38 case 3 : // W
el17sm 50:2c5cb92a5361 39 player->set_position(85, 25);
el17sm 50:2c5cb92a5361 40 break;
el17sm 50:2c5cb92a5361 41 case 4 : // Default where an exit does not exist (starting position)
el17sm 50:2c5cb92a5361 42 player->set_position(39, 30);
el17sm 50:2c5cb92a5361 43 break;
el17sm 50:2c5cb92a5361 44 }
el17sm 50:2c5cb92a5361 45 }
el17sm 50:2c5cb92a5361 46
el17sm 28:98848e6a77a2 47 void RoomEngine::entrance_scene(N5110 &lcd, Gamepad &gamepad)
el17sm 27:a1b41626f57c 48 {
el17sm 28:98848e6a77a2 49 int side = check_player_room_position();
el17sm 28:98848e6a77a2 50 for(int i = 0; i<50; i++) {
el17sm 49:3f83ed62d123 51 switch(side) { // Setting movement of player as it enters the screen (velocity)
el17sm 28:98848e6a77a2 52 case 0 :
el17sm 49:3f83ed62d123 53 set_mapped_coord(0, -((4 + player->get_sprite_height()) / (50 * player->get_velocity()))); break;
el17sm 28:98848e6a77a2 54 case 1 :
el17sm 49:3f83ed62d123 55 set_mapped_coord(-((4 + player->get_hitbox_width()) / (50 * player->get_velocity())), 0); break;
el17sm 28:98848e6a77a2 56 case 2 :
el17sm 49:3f83ed62d123 57 set_mapped_coord(0, ((4 + player->get_hitbox_height()) / (50 * player->get_velocity()))); break;
el17sm 28:98848e6a77a2 58 case 3 :
el17sm 49:3f83ed62d123 59 set_mapped_coord(((4 + player->get_hitbox_width()) / (50 * player->get_velocity())), 0); break;
el17sm 28:98848e6a77a2 60 }
el17sm 28:98848e6a77a2 61 move_player();
el17sm 28:98848e6a77a2 62 render(lcd, gamepad);
el17sm 49:3f83ed62d123 63 if (0.75 - (i * 0.005) > _global_contrast) { // Fade in
el17sm 30:ec915d24d3e9 64 lcd.setContrast(0.75 - (i * 0.005));
el17sm 49:3f83ed62d123 65 } else { lcd.setContrast(_global_contrast);}
el17sm 28:98848e6a77a2 66 }
el17sm 28:98848e6a77a2 67 }
el17sm 28:98848e6a77a2 68
el17sm 50:2c5cb92a5361 69 int RoomEngine::check_player_room_position() // returns 0,1,2,3 if the player exits the respective directions, returns 4 if the player is in the room
el17sm 50:2c5cb92a5361 70 {
el17sm 50:2c5cb92a5361 71 if (player->get_pos_y() < 0) {
el17sm 50:2c5cb92a5361 72 return 0;
el17sm 50:2c5cb92a5361 73 }
el17sm 50:2c5cb92a5361 74 else if (player->get_pos_x() > WIDTH - (player->get_hitbox_width())) {
el17sm 50:2c5cb92a5361 75 return 1;
el17sm 50:2c5cb92a5361 76 }
el17sm 50:2c5cb92a5361 77 else if (player->get_pos_y() > HEIGHT - (player->get_hitbox_height())) {
el17sm 50:2c5cb92a5361 78 return 2;
el17sm 50:2c5cb92a5361 79 }
el17sm 50:2c5cb92a5361 80 else if (player->get_pos_x() < 0) {
el17sm 50:2c5cb92a5361 81 return 3;
el17sm 50:2c5cb92a5361 82 }
el17sm 50:2c5cb92a5361 83 else {
el17sm 50:2c5cb92a5361 84 return 4;
el17sm 50:2c5cb92a5361 85 }
el17sm 50:2c5cb92a5361 86 }
el17sm 50:2c5cb92a5361 87
el17sm 50:2c5cb92a5361 88 void RoomEngine::read_input(Gamepad &gamepad) // Updates member variables for easier access
el17sm 50:2c5cb92a5361 89 {
el17sm 50:2c5cb92a5361 90 _L = gamepad.check_event(Gamepad::L_PRESSED);
el17sm 50:2c5cb92a5361 91 _R = gamepad.check_event(Gamepad::R_PRESSED);
el17sm 50:2c5cb92a5361 92 _A = gamepad.check_event(Gamepad::A_PRESSED);
el17sm 50:2c5cb92a5361 93 _B = gamepad.check_event(Gamepad::B_PRESSED);
el17sm 50:2c5cb92a5361 94 _X = gamepad.check_event(Gamepad::X_PRESSED);
el17sm 50:2c5cb92a5361 95 _Y = gamepad.check_event(Gamepad::Y_PRESSED);
el17sm 50:2c5cb92a5361 96 mapped_coord = gamepad.get_mapped_coord();
el17sm 50:2c5cb92a5361 97 }
el17sm 50:2c5cb92a5361 98
el17sm 50:2c5cb92a5361 99 void RoomEngine::update(int &number_of_enemies_killed) // Updates all HP, deletes dead entities, increment score (kills),
el17sm 50:2c5cb92a5361 100 { // checks wall collisions (exclusive for entity:walls), movements for all entities and player action detection
el17sm 50:2c5cb92a5361 101 room->update_doorways();
el17sm 50:2c5cb92a5361 102 check_damage();
el17sm 50:2c5cb92a5361 103 check_enemies_death(number_of_enemies_killed);
el17sm 50:2c5cb92a5361 104 check_walls_collision();
el17sm 50:2c5cb92a5361 105 move();
el17sm 50:2c5cb92a5361 106 player->buttons(_A, _B, _Y, _X);
el17sm 50:2c5cb92a5361 107 }
el17sm 50:2c5cb92a5361 108
el17sm 50:2c5cb92a5361 109 void RoomEngine::check_damage()
el17sm 50:2c5cb92a5361 110 {
el17sm 50:2c5cb92a5361 111 check_damage_player(); // damage player if collide with enemy / heal if collide with hearts
el17sm 50:2c5cb92a5361 112 check_damage_enemies(); // damage enemy if collide with player's bullets
el17sm 50:2c5cb92a5361 113 }
el17sm 50:2c5cb92a5361 114
el17sm 50:2c5cb92a5361 115
el17sm 50:2c5cb92a5361 116 void RoomEngine::check_enemies_death(int &number_of_enemies_killed) // Deletes dead enemies, spawn hearts based on chance(defined in each enemy) and increments kill score
el17sm 50:2c5cb92a5361 117 {
el17sm 50:2c5cb92a5361 118 // Enemy Death
el17sm 50:2c5cb92a5361 119 for (int i = 0; i < MAX_ENEMIES; i++) {
el17sm 50:2c5cb92a5361 120 if((room->valid_enemies[i]) && (room->enemies[i]->get_hp() <= 0)) {
el17sm 50:2c5cb92a5361 121 if ((rand() % 100) < room->enemies[i]->get_hp_drop_chance()){
el17sm 50:2c5cb92a5361 122 for (int j = 0; j < MAX_ENEMIES; j++) {
el17sm 50:2c5cb92a5361 123 if (!room->valid_collectibles[j]) {
el17sm 50:2c5cb92a5361 124 room->collectibles[j] = new Health(room->enemies[i]->get_pos_x(), room->enemies[i]->get_pos_y()); // Spawn a health drop
el17sm 50:2c5cb92a5361 125 room->valid_collectibles[j] = true;
el17sm 50:2c5cb92a5361 126 break;
el17sm 50:2c5cb92a5361 127 }
el17sm 50:2c5cb92a5361 128 }
el17sm 50:2c5cb92a5361 129 }
el17sm 50:2c5cb92a5361 130 delete room->enemies[i];
el17sm 50:2c5cb92a5361 131 room->valid_enemies[i] = false;
el17sm 50:2c5cb92a5361 132 number_of_enemies_killed++;
el17sm 50:2c5cb92a5361 133 }
el17sm 50:2c5cb92a5361 134 }
el17sm 50:2c5cb92a5361 135 }
el17sm 50:2c5cb92a5361 136
el17sm 50:2c5cb92a5361 137 void RoomEngine::check_walls_collision() // Undo moves of player and enemy if colliding with entity:wall and kills bullets when colliding with entity:wall
el17sm 50:2c5cb92a5361 138 { // Currently unused (room types 0 and 10 do not spawn entity:wall)
el17sm 50:2c5cb92a5361 139 // Enemy
el17sm 50:2c5cb92a5361 140 for (int i = 0; i < MAX_ENEMIES; i++) {
el17sm 50:2c5cb92a5361 141 if(room->valid_enemies[i]) { // Undo move of every valid enemy upon collision with entity:wall
el17sm 50:2c5cb92a5361 142 room->enemies[i]->undo_move_x(entity_move_check_x(room->enemies[i], room->walls, 2, 10, room->valid_walls));
el17sm 50:2c5cb92a5361 143 room->enemies[i]->undo_move_y(entity_move_check_y(room->enemies[i], room->walls, 2, 10, room->valid_walls));
el17sm 50:2c5cb92a5361 144 }
el17sm 50:2c5cb92a5361 145 }
el17sm 50:2c5cb92a5361 146 // Player
el17sm 50:2c5cb92a5361 147 player->undo_move_x(entity_move_check_x(player, room->walls, 2, 10, room->valid_walls));
el17sm 50:2c5cb92a5361 148 player->undo_move_y(entity_move_check_y(player, room->walls, 2, 10, room->valid_walls));
el17sm 50:2c5cb92a5361 149 // Bullets
el17sm 50:2c5cb92a5361 150 for (int i = 0; i < bullets_max; i++) {
el17sm 50:2c5cb92a5361 151 for (int j = 0; j < 2; j++) { // given that both walls and bullets are valid, check if they're colliding
el17sm 50:2c5cb92a5361 152 if ((player->valid_bullets[i]) && (room->valid_walls[j]) && (entity_collision(*player->bullets_array[i], *room->walls[j]))) {
el17sm 50:2c5cb92a5361 153 delete player->bullets_array[i]; player->valid_bullets[i] = false;
el17sm 50:2c5cb92a5361 154 }
el17sm 50:2c5cb92a5361 155 }
el17sm 50:2c5cb92a5361 156 }
el17sm 50:2c5cb92a5361 157 }
el17sm 50:2c5cb92a5361 158
el17sm 50:2c5cb92a5361 159 void RoomEngine::move()
el17sm 50:2c5cb92a5361 160 {
el17sm 50:2c5cb92a5361 161 move_player();
el17sm 50:2c5cb92a5361 162 move_enemies();
el17sm 50:2c5cb92a5361 163 }
el17sm 50:2c5cb92a5361 164
el17sm 50:2c5cb92a5361 165 void RoomEngine::render(N5110 &lcd, Gamepad &gamepad)
el17sm 50:2c5cb92a5361 166 {
el17sm 50:2c5cb92a5361 167 pause_detection(lcd, gamepad);
el17sm 50:2c5cb92a5361 168 lcd.clear();
el17sm 50:2c5cb92a5361 169 draw(lcd);
el17sm 50:2c5cb92a5361 170 lcd.refresh();
el17sm 50:2c5cb92a5361 171 wait_ms(1000/40); // setting FPS
el17sm 50:2c5cb92a5361 172 }
el17sm 50:2c5cb92a5361 173
el17sm 50:2c5cb92a5361 174 void RoomEngine::pause_detection(N5110 &lcd, Gamepad &gamepad)
el17sm 50:2c5cb92a5361 175 {
el17sm 50:2c5cb92a5361 176 if(gamepad.check_event(Gamepad::START_PRESSED)) {
el17sm 50:2c5cb92a5361 177 draw_health(lcd);
el17sm 50:2c5cb92a5361 178 char * paused_screen = lcd.readScreen(); // Saves current screen
el17sm 50:2c5cb92a5361 179 int pause_timer = 0;
el17sm 50:2c5cb92a5361 180 lcd.drawSpriteTransparent(20, 20, 9, 45, (char *)pause_sprite);
el17sm 50:2c5cb92a5361 181 // Ensures that Start button is toggled twice to exit loop
el17sm 50:2c5cb92a5361 182 while(gamepad.check_event(Gamepad::START_PRESSED)) {
el17sm 50:2c5cb92a5361 183 draw_pause_screen(lcd, paused_screen, pause_timer);
el17sm 50:2c5cb92a5361 184 }
el17sm 50:2c5cb92a5361 185 while(!gamepad.check_event(Gamepad::START_PRESSED)) {
el17sm 50:2c5cb92a5361 186 draw_pause_screen(lcd, paused_screen, pause_timer);
el17sm 50:2c5cb92a5361 187 }
el17sm 50:2c5cb92a5361 188 while(gamepad.check_event(Gamepad::START_PRESSED)) {
el17sm 50:2c5cb92a5361 189 draw_pause_screen(lcd, paused_screen, pause_timer);
el17sm 50:2c5cb92a5361 190 }
el17sm 50:2c5cb92a5361 191 }
el17sm 50:2c5cb92a5361 192 }
el17sm 50:2c5cb92a5361 193
el17sm 50:2c5cb92a5361 194 void RoomEngine::draw_pause_screen(N5110 &lcd, char * paused_screen, int &pause_timer)
el17sm 50:2c5cb92a5361 195 {
el17sm 50:2c5cb92a5361 196 lcd.clear();
el17sm 50:2c5cb92a5361 197 lcd.drawSprite(0, 0, HEIGHT, WIDTH, paused_screen);
el17sm 50:2c5cb92a5361 198 if (pause_timer % 20 < 10) { // Draws pause sprite only 10/20 frames of pause_timer, this way pause blinks
el17sm 50:2c5cb92a5361 199 lcd.drawSpriteTransparent(20, 20, 9, 45, (char *)pause_sprite);
el17sm 50:2c5cb92a5361 200 }
el17sm 50:2c5cb92a5361 201 lcd.refresh();
el17sm 50:2c5cb92a5361 202 pause_timer++;
el17sm 50:2c5cb92a5361 203 wait_ms(1000/40);
el17sm 50:2c5cb92a5361 204 }
el17sm 50:2c5cb92a5361 205
el17sm 50:2c5cb92a5361 206 void RoomEngine::draw(N5110 &lcd) // Draws everything onto the screen
el17sm 50:2c5cb92a5361 207 {
el17sm 50:2c5cb92a5361 208 room->draw_room(lcd);
el17sm 50:2c5cb92a5361 209 for(int j = 0; j < HEIGHT; j++) { // To create a 3D illusion, all entities are drawn at the order of it's hitbox height (highest to lowest)
el17sm 50:2c5cb92a5361 210 if (j == player->get_pos_y()) {
el17sm 50:2c5cb92a5361 211 player->draw(lcd);
el17sm 50:2c5cb92a5361 212 }
el17sm 50:2c5cb92a5361 213 player->draw_bullets(lcd, j);
el17sm 50:2c5cb92a5361 214 room->draw(lcd, j);
el17sm 50:2c5cb92a5361 215 }
el17sm 50:2c5cb92a5361 216
el17sm 50:2c5cb92a5361 217 room->draw_room_overlay(lcd); // Special overlay such as side doorways and boss doorways
el17sm 50:2c5cb92a5361 218
el17sm 50:2c5cb92a5361 219 if (_L) { // Displaying Hearts if L is pressed
el17sm 50:2c5cb92a5361 220 draw_health(lcd);
el17sm 50:2c5cb92a5361 221 }
el17sm 50:2c5cb92a5361 222 }
el17sm 50:2c5cb92a5361 223
el17sm 50:2c5cb92a5361 224 void RoomEngine::draw_health(N5110 &lcd)
el17sm 50:2c5cb92a5361 225 {
el17sm 50:2c5cb92a5361 226 for (int i = 0; i < player->get_hp(); i++){ // For every health, draw a heart at x pos i*10
el17sm 50:2c5cb92a5361 227 lcd.drawSpriteTransparent(i*10,
el17sm 50:2c5cb92a5361 228 0,
el17sm 50:2c5cb92a5361 229 player->get_hearts_height(),
el17sm 50:2c5cb92a5361 230 player->get_hearts_width(),
el17sm 50:2c5cb92a5361 231 player->get_hearts_sprite());
el17sm 50:2c5cb92a5361 232 }
el17sm 50:2c5cb92a5361 233 }
el17sm 50:2c5cb92a5361 234
el17sm 50:2c5cb92a5361 235 void RoomEngine::exit_scene(N5110 &lcd, Gamepad &gamepad) // Plays an exit scene
el17sm 28:98848e6a77a2 236 {
el17sm 28:98848e6a77a2 237 int side = check_player_room_position();
el17sm 28:98848e6a77a2 238
el17sm 28:98848e6a77a2 239 for(int i = 0; i<50; i++) {
el17sm 49:3f83ed62d123 240 switch(side) { // Setting movement of player as it exits the screen (velocity)
el17sm 28:98848e6a77a2 241 case 0 :
el17sm 49:3f83ed62d123 242 set_mapped_coord(0, (player->get_velocity() / 2)); break;
el17sm 28:98848e6a77a2 243 case 1 :
el17sm 49:3f83ed62d123 244 set_mapped_coord((player->get_velocity() / 2), 0); break;
el17sm 28:98848e6a77a2 245 case 2 :
el17sm 49:3f83ed62d123 246 set_mapped_coord(0, -(player->get_velocity() / 2)); break;
el17sm 28:98848e6a77a2 247 case 3 :
el17sm 49:3f83ed62d123 248 set_mapped_coord(-(player->get_velocity() / 2), 0); break;
el17sm 28:98848e6a77a2 249 }
el17sm 28:98848e6a77a2 250 move_player();
el17sm 28:98848e6a77a2 251 render(lcd, gamepad);
el17sm 49:3f83ed62d123 252 lcd.setContrast(_global_contrast + (i * 0.005)); // Fade out
el17sm 28:98848e6a77a2 253 }
el17sm 30:ec915d24d3e9 254 lcd.setContrast(0.75);
el17sm 27:a1b41626f57c 255 }
el17sm 27:a1b41626f57c 256
el17sm 50:2c5cb92a5361 257 void RoomEngine::update_current_room() // Increments room coord depending on direction
el17sm 29:6b8411bb040a 258 {
el17sm 29:6b8411bb040a 259 switch(check_player_room_position()) {
el17sm 29:6b8411bb040a 260 case 0 :
el17sm 46:f09711580d4a 261 _room_y--;
el17sm 29:6b8411bb040a 262 break;
el17sm 29:6b8411bb040a 263 case 1 :
el17sm 29:6b8411bb040a 264 _room_x++;
el17sm 29:6b8411bb040a 265 break;
el17sm 29:6b8411bb040a 266 case 2 :
el17sm 46:f09711580d4a 267 _room_y++;
el17sm 29:6b8411bb040a 268 break;
el17sm 29:6b8411bb040a 269 case 3 :
el17sm 29:6b8411bb040a 270 _room_x--;
el17sm 29:6b8411bb040a 271 break;
el17sm 29:6b8411bb040a 272 default :
el17sm 29:6b8411bb040a 273 break;
el17sm 29:6b8411bb040a 274 }
el17sm 29:6b8411bb040a 275 }
el17sm 29:6b8411bb040a 276
el17sm 29:6b8411bb040a 277 // Public Accessors
el17sm 29:6b8411bb040a 278
el17sm 29:6b8411bb040a 279 int RoomEngine::get_room_x()
el17sm 29:6b8411bb040a 280 {
el17sm 29:6b8411bb040a 281 return _room_x;
el17sm 29:6b8411bb040a 282 }
el17sm 29:6b8411bb040a 283 int RoomEngine::get_room_y()
el17sm 29:6b8411bb040a 284 {
el17sm 29:6b8411bb040a 285 return _room_y;
el17sm 29:6b8411bb040a 286 }
el17sm 29:6b8411bb040a 287
el17sm 28:98848e6a77a2 288 // Private Mutators
el17sm 28:98848e6a77a2 289
el17sm 28:98848e6a77a2 290 void RoomEngine::set_input(bool L, bool R, bool A, bool B, bool X, bool Y, float mapped_x, float mapped_y)
el17sm 28:98848e6a77a2 291 {
el17sm 28:98848e6a77a2 292 _L = L;
el17sm 28:98848e6a77a2 293 _R = R;
el17sm 28:98848e6a77a2 294 _A = A;
el17sm 28:98848e6a77a2 295 _B = B;
el17sm 28:98848e6a77a2 296 _X = X;
el17sm 28:98848e6a77a2 297 _Y = Y;
el17sm 28:98848e6a77a2 298 set_mapped_coord(mapped_x, mapped_y);
el17sm 28:98848e6a77a2 299 }
el17sm 28:98848e6a77a2 300
el17sm 28:98848e6a77a2 301 void RoomEngine::set_mapped_coord(float x, float y)
el17sm 28:98848e6a77a2 302 {
el17sm 28:98848e6a77a2 303 mapped_coord.x = x;
el17sm 28:98848e6a77a2 304 mapped_coord.y = y;
el17sm 28:98848e6a77a2 305 }
el17sm 28:98848e6a77a2 306
el17sm 50:2c5cb92a5361 307 // Methods
el17sm 26:abbc19edc5c1 308
el17sm 27:a1b41626f57c 309 bool RoomEngine::entity_collision(Entity &a, Entity &b) // returns true if the two entity hitboxes collide
el17sm 26:abbc19edc5c1 310 {
el17sm 50:2c5cb92a5361 311 if (((b.get_pos_x() <= a.get_pos_x()) && (a.get_pos_x() <= b.get_pos_x() + b.get_hitbox_width() - 1)) || // if Entity A's x of left side of the hitbox is inside Entity B's hitbox x range
el17sm 50:2c5cb92a5361 312 ((b.get_pos_x() <= a.get_pos_x() + a.get_hitbox_width() - 1) && (a.get_pos_x() + a.get_hitbox_width() - 1 <= b.get_pos_x() + b.get_hitbox_width() - 1))) { // if Entity A's x of right side of the hitbox is inside Entity B's hitbox x range
el17sm 50:2c5cb92a5361 313 if (((b.get_pos_y() <= a.get_pos_y()) && (a.get_pos_y() <= b.get_pos_y() + b.get_hitbox_height() - 1)) || // if Entity A's y of top side of the hitbox is inside Entity B's hitbox y range
el17sm 50:2c5cb92a5361 314 ((b.get_pos_y() <= a.get_pos_y() + a.get_hitbox_height() - 1) && (a.get_pos_y() + a.get_hitbox_height() - 1 <= b.get_pos_y() + b.get_hitbox_height() - 1))) { // if Entity A's y of bottom side of the hitbox is inside Entity B's hitbox y range
el17sm 26:abbc19edc5c1 315 return true;
el17sm 26:abbc19edc5c1 316 }
el17sm 26:abbc19edc5c1 317 }
el17sm 26:abbc19edc5c1 318 return 0;
el17sm 26:abbc19edc5c1 319 }
el17sm 26:abbc19edc5c1 320
el17sm 50:2c5cb92a5361 321 // returns true if the hitbox of "entity a" collides with any hitboxes of entities within "array" as "entity a" moves on the x direction
el17sm 27:a1b41626f57c 322 float RoomEngine::entity_move_check_x(Entity *a, Entity *array[], int no_of_enemies, int current_entity, bool valid_enemies[])
el17sm 26:abbc19edc5c1 323 {
el17sm 50:2c5cb92a5361 324 for (int i = 0; i < no_of_enemies; i++) { // For every enemy = Entity B
el17sm 49:3f83ed62d123 325 if ((valid_enemies[i]) && (i != current_entity)) { // only check if entity b exists and entity a is not the same as entity b
el17sm 50:2c5cb92a5361 326 if (((array[i]->get_prev_pos_x() <= a->get_pos_x()) && (a->get_pos_x() <= array[i]->get_prev_pos_x() + array[i]->get_hitbox_width() - 1)) || // Same as entity_collision, except that Entity B's x position is its previous x position
el17sm 49:3f83ed62d123 327 ((array[i]->get_prev_pos_x() <= a->get_pos_x() + a->get_hitbox_width() - 1) && (a->get_pos_x() + a->get_hitbox_width() - 1 <= array[i]->get_prev_pos_x() + array[i]->get_hitbox_width() - 1))) {
el17sm 49:3f83ed62d123 328 if (((array[i]->get_prev_pos_y() <= a->get_prev_pos_y()) && (a->get_prev_pos_y() <= array[i]->get_prev_pos_y() + array[i]->get_hitbox_height() - 1)) ||
el17sm 49:3f83ed62d123 329 ((array[i]->get_prev_pos_y() <= a->get_prev_pos_y() + a->get_hitbox_height() - 1) && (a->get_prev_pos_y() + a->get_hitbox_height() - 1 <= array[i]->get_prev_pos_y() + array[i]->get_hitbox_height() - 1))) {
el17sm 49:3f83ed62d123 330 return (2*((a->get_pos_x() > array[i]->get_prev_pos_x()) - 0.5));
el17sm 26:abbc19edc5c1 331 }
el17sm 26:abbc19edc5c1 332 }
el17sm 26:abbc19edc5c1 333 }
el17sm 26:abbc19edc5c1 334 }
el17sm 26:abbc19edc5c1 335 return 0;
el17sm 26:abbc19edc5c1 336 }
el17sm 26:abbc19edc5c1 337
el17sm 50:2c5cb92a5361 338 // returns true if the hitbox of "entity a" collides with any hitboxes of entities within "array" as "entity a" moves on the y direction
el17sm 27:a1b41626f57c 339 float RoomEngine::entity_move_check_y(Entity *a, Entity *array[], int no_of_enemies, int current_entity, bool valid_enemies[])
el17sm 26:abbc19edc5c1 340 {
el17sm 50:2c5cb92a5361 341 for (int i = 0; i < no_of_enemies; i++) { // For every enemy = Entity B
el17sm 49:3f83ed62d123 342 if ((valid_enemies[i]) && (i != current_entity)) { // only check if entity b exists and entity a is not the same as entity b
el17sm 50:2c5cb92a5361 343 if (((array[i]->get_prev_pos_x() <= a->get_prev_pos_x()) && (a->get_prev_pos_x() <= array[i]->get_prev_pos_x() + array[i]->get_hitbox_width() - 1)) || // Same as entity_collision, except that Entity B's y position is its previous y position
el17sm 49:3f83ed62d123 344 ((array[i]->get_prev_pos_x() <= a->get_prev_pos_x() + a->get_hitbox_width() - 1) && (a->get_prev_pos_x() + a->get_hitbox_width() - 1 <= array[i]->get_prev_pos_x() + array[i]->get_hitbox_width() - 1))) {
el17sm 49:3f83ed62d123 345 if (((array[i]->get_prev_pos_y() <= a->get_pos_y()) && (a->get_pos_y() <= array[i]->get_prev_pos_y() + array[i]->get_hitbox_height() - 1)) ||
el17sm 49:3f83ed62d123 346 ((array[i]->get_prev_pos_y() <= a->get_pos_y() + a->get_hitbox_height() - 1) && (a->get_pos_y() + a->get_hitbox_height() - 1 <= array[i]->get_prev_pos_y() + array[i]->get_hitbox_height() - 1))) {
el17sm 49:3f83ed62d123 347 return (2*((a->get_pos_y() > array[i]->get_prev_pos_y()) - 0.5));
el17sm 26:abbc19edc5c1 348 }
el17sm 26:abbc19edc5c1 349 }
el17sm 26:abbc19edc5c1 350 }
el17sm 26:abbc19edc5c1 351 }
el17sm 26:abbc19edc5c1 352 return 0;
el17sm 26:abbc19edc5c1 353 }
el17sm 26:abbc19edc5c1 354
el17sm 27:a1b41626f57c 355 void RoomEngine::check_damage_player()
el17sm 26:abbc19edc5c1 356 {
el17sm 26:abbc19edc5c1 357 for (int i = 0; i < MAX_ENEMIES; i++) {
el17sm 50:2c5cb92a5361 358 if (room->valid_enemies[i]) { // Checking each valid enemy
el17sm 27:a1b41626f57c 359 if(entity_collision(*player, *room->enemies[i])) {
el17sm 27:a1b41626f57c 360 player->take_damage(room->enemies[i]->get_attack());
el17sm 28:98848e6a77a2 361 break; // only let 1 enemy damage player at a time
el17sm 26:abbc19edc5c1 362 }
el17sm 26:abbc19edc5c1 363 }
el17sm 50:2c5cb92a5361 364 if (room->valid_collectibles[i]) { // Checking each valid collectible (hearts, coins)
el17sm 37:a404860171a9 365 if(entity_collision(*player, *room->collectibles[i])) {
el17sm 37:a404860171a9 366 player->take_damage(room->collectibles[i]->get_attack());
el17sm 37:a404860171a9 367 delete room->collectibles[i];
el17sm 37:a404860171a9 368 room->valid_collectibles[i] = false;
el17sm 37:a404860171a9 369 break; // only let 1 heart heal player at a time
el17sm 37:a404860171a9 370 }
el17sm 37:a404860171a9 371 }
el17sm 27:a1b41626f57c 372 }
el17sm 26:abbc19edc5c1 373 }
el17sm 26:abbc19edc5c1 374
el17sm 27:a1b41626f57c 375 void RoomEngine::check_damage_enemies()
el17sm 26:abbc19edc5c1 376 {
el17sm 26:abbc19edc5c1 377 for (int i = 0; i < bullets_max; i++) {
el17sm 27:a1b41626f57c 378 if (player->valid_bullets[i]) {
el17sm 55:fc618f82d1d0 379 if (!(player->delete_out_of_bounds_bullets(room->get_current_map_2d(), room->get_doorways()))) { // Delete any bullet that goes out the screen or hits walls, if none, then
el17sm 26:abbc19edc5c1 380 for (int j = 0; j < MAX_ENEMIES; j++) {
el17sm 50:2c5cb92a5361 381 if (room->valid_enemies[j] && (entity_collision(*player->bullets_array[i], *room->enemies[j]))) { // Delete bullets and damage enemy if player bullets collide with any enemy
el17sm 27:a1b41626f57c 382 room->enemies[j]->take_damage(player->get_attack());
el17sm 50:2c5cb92a5361 383 delete player->bullets_array[i]; player->valid_bullets[i] = false;
el17sm 26:abbc19edc5c1 384 break;
el17sm 26:abbc19edc5c1 385 }
el17sm 26:abbc19edc5c1 386 }
el17sm 26:abbc19edc5c1 387 }
el17sm 26:abbc19edc5c1 388 }
el17sm 26:abbc19edc5c1 389 }
el17sm 26:abbc19edc5c1 390 }
el17sm 26:abbc19edc5c1 391
el17sm 27:a1b41626f57c 392 void RoomEngine::move_player()
el17sm 26:abbc19edc5c1 393 {
el17sm 29:6b8411bb040a 394 player->move(mapped_coord.x, mapped_coord.y, room->get_current_map_2d(), room->get_doorways());
el17sm 26:abbc19edc5c1 395 }
el17sm 26:abbc19edc5c1 396
el17sm 27:a1b41626f57c 397 void RoomEngine::move_enemies()
el17sm 26:abbc19edc5c1 398 {
el17sm 26:abbc19edc5c1 399 // Actual Movement of Enemies
el17sm 26:abbc19edc5c1 400 for (int i = 0; i < MAX_ENEMIES; i++) {
el17sm 27:a1b41626f57c 401 if (room->valid_enemies[i]) {
el17sm 27:a1b41626f57c 402 room->enemies[i]->update_prev_pos();
el17sm 29:6b8411bb040a 403 room->enemies[i]->move(player->get_pos_x(), player->get_pos_y(), room->get_current_map_2d(), room->get_doorways());
el17sm 26:abbc19edc5c1 404 }
el17sm 27:a1b41626f57c 405 }
el17sm 26:abbc19edc5c1 406 // Entity Collision Repulsion
el17sm 26:abbc19edc5c1 407 for (int i = 0; i < MAX_ENEMIES; i++) {
el17sm 37:a404860171a9 408 if (room->valid_enemies[i]) {
el17sm 50:2c5cb92a5361 409 room->enemies[i]->position_add_x(entity_move_check_x(room->enemies[i], room->enemies, MAX_ENEMIES, i, room->valid_enemies)); // add 1 x position if collide
el17sm 50:2c5cb92a5361 410 room->enemies[i]->position_add_y(entity_move_check_y(room->enemies[i], room->enemies, MAX_ENEMIES, i, room->valid_enemies)); // add 1 y position if collide
el17sm 26:abbc19edc5c1 411 }
el17sm 27:a1b41626f57c 412 }
el17sm 26:abbc19edc5c1 413 }