A rouge-like rpg, heavily inspired on the binding of isaac. Running on a FRDM-K64F Mbed board. C++.
Dependencies: mbed MotionSensor
Diff: RoomEngine/RoomEngine.cpp
- Revision:
- 26:abbc19edc5c1
- Child:
- 27:a1b41626f57c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RoomEngine/RoomEngine.cpp Mon Apr 29 02:45:17 2019 +0000 @@ -0,0 +1,283 @@ +#include "RoomEngine.h" + +void GameEngine::init() +{ + Player player(39, 27); +} + +void GameEngine::read_input(Gamepad &gamepad) +{ + _L = gamepad.check_event(Gamepad::L_PRESSED); + _R = gamepad.check_event(Gamepad::R_PRESSED); + _START = gamepad.check_event(Gamepad::START_PRESSED); + _BACK = gamepad.check_event(Gamepad::BACK_PRESSED); + _A = gamepad.check_event(Gamepad::A_PRESSED); + _B = gamepad.check_event(Gamepad::B_PRESSED); + _X = gamepad.check_event(Gamepad::X_PRESSED); + _Y = gamepad.check_event(Gamepad::Y_PRESSED); + mapped_coord = gamepad.get_mapped_coord(); +} + +void GameEngine::update(N5110 &lcd) +{ + check_damage(); + check_death(); + move(); + minimap_detection(lcd); + pause_detection(lcd); +} + +void GameEngine::draw(N5110 &lcd) +{ + lcd.drawSprite(0,0,screen_height,screen_width,(int *)level_map[1]); + draw_player(lcd); + draw_enemies(lcd); + draw_bullets(lcd); + draw_health(lcd); +} + +// Private Functions + +bool GameEngine::entity_collision(Entity &a, Entity &b) // returns true if the two entity hitboxes collide +{ + if (((b.get_pos_x() <= a.get_pos_x()) && (a.get_pos_x() <= b.get_pos_x() + b.get_hitbox_width() - 1)) || + ((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 (((b.get_pos_y() <= a.get_pos_y()) && (a.get_pos_y() <= b.get_pos_y() + b.get_hitbox_height() - 1)) || + ((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))) { + return true; + } + } + return 0; +} + +// returns true if the hitbox of "entity a" collides with any hitboxes of enttities within "array" as "entity a" moves on the x direction +float GameEngine::entity_move_check_x(Entity *a, Entity *array[], int no_of_enemies, int current_entity, bool valid_enemies[]) +{ + for (int i = 0; i < no_of_enemies; i++) { + if (valid_enemies[i]) { + if(i != current_entity) { + 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)) || + ((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))) { + 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)) || + ((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))) { + return (2*((a->get_pos_x() > array[i]->get_prev_pos_x()) - 0.5)); + } + } + } + } + } + return 0; +} + +// returns true if the hitbox of "entity a" collides with any hitboxes of enttities within "array" as "entity a" moves on the y direction +float GameEngine::entity_move_check_y(Entity *a, Entity *array[], int no_of_enemies, int current_entity, bool valid_enemies[]) +{ + for (int i = 0; i < no_of_enemies; i++) { + if (valid_enemies[i]) { + if(i != current_entity) { + 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)) || + ((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))) { + 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)) || + ((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))) { + return (2*((a->get_pos_y() > array[i]->get_prev_pos_y()) - 0.5)); + } + } + } + } + } + return 0; +} + +void GameEngine::check_damage() +{ + check_damage_player(); + check_damage_enemies(); +} + +void GameEngine::check_damage_player() +{ + for (int i = 0; i < MAX_ENEMIES; i++) { + if (room.valid_enemies[i]) { + if(entity_collision(player, *room.enemies[i])) { + player.take_damage(room.enemies[i]->get_attack()); + } + } + }; +} + +void GameEngine::check_damage_enemies() +{ + for (int i = 0; i < bullets_max; i++) { + if (player.valid_bullets[i]) { + if (player.bullets_array[i]->out_of_bounds_check()) { + player.valid_bullets[i] = false; + delete player.bullets_array[i]; + } else { + for (int j = 0; j < MAX_ENEMIES; j++) { + if (room.valid_enemies[j] && (entity_collision(*player.bullets_array[i], *room.enemies[j]))) { + room.enemies[j]->take_damage(player.get_attack()); + player.valid_bullets[i] = false; + delete player.bullets_array[i]; + break; + } + } + } + } + } +} + +void GameEngine::check_death() +{ + // Player Death + if (player.get_hp() <= 0) { + } + // Enemy Death + for (int i = 0; i < MAX_ENEMIES; i++) { + if (room.valid_enemies[i]) { + if(room.enemies[i]->get_hp() <= 0) { + room.valid_enemies[i] = false; + delete room.enemies[i]; + } + } + } +} + +void GameEngine::move() +{ + move_player(); + move_enemies(); + move_bullets(); +} + +void GameEngine::move_player() +{ + player.move(mapped_coord.x, mapped_coord.y); +} + +void GameEngine::move_enemies() +{ + // Actual Movement of Enemies + for (int i = 0; i < MAX_ENEMIES; i++) { + if (room.valid_enemies[i]) { + room.enemies[i]->update_prev_pos(); + room.enemies[i]->move(player.get_pos_x(), player.get_pos_y()); + } + }; + // Entity Collision Repulsion + for (int i = 0; i < MAX_ENEMIES; i++) { + if (room.valid_enemies[i]) { + room.enemies[i]->position_add_x(entity_move_check_x(room.enemies[i], room.enemies, MAX_ENEMIES, i, room.valid_enemies)); + room.enemies[i]->position_add_y(entity_move_check_y(room.enemies[i], room.enemies, MAX_ENEMIES, i, room.valid_enemies)); + } + }; +} + +void GameEngine::move_bullets() +{ + for (int i = 0; i < bullets_max; i++) { + if (player.valid_bullets[i]) { + player.bullets_array[i]->move(player.get_bullet_speed(), 0); + } + }; +} + +void GameEngine::minimap_detection(N5110 &lcd) +{ + while(_BACK) { + wait(0.05); + lcd.clear(); + }; +} + +void GameEngine::pause_detection(N5110 &lcd) +{ + if(_START) { + lcd.drawSpriteTransparent(0, + 0, + player.get_hearts_height(), + player.get_hearts_width(), + player.get_hearts_sprite()); + int * paused_screen = lcd.readScreen(); + int pause_timer = 2; + lcd.drawSpriteTransparent(20, 20, 9, 45, (int *)pause_sprite); + wait(0.05); + while(_START) { + lcd.clear(); + lcd.drawSprite(0, 0, HEIGHT, WIDTH, paused_screen); + if (pause_timer % 10 <= 4) { + lcd.drawSpriteTransparent(20, 20, 9, 45, (int *)pause_sprite); + } + lcd.refresh(); + pause_timer++; + wait_ms(1000/40); + }; + wait(0.05); + pause_timer += 2; + while(!_START) { + lcd.clear(); + lcd.drawSprite(0, 0, HEIGHT, WIDTH, paused_screen); + if (pause_timer % 10 <= 4) { + lcd.drawSpriteTransparent(20, 20, 9, 45, (int *)pause_sprite); + } + lcd.refresh(); + pause_timer++; + wait_ms(1000/40); + }; + wait(0.05); + pause_timer += 2; + while(_START) { + lcd.clear(); + lcd.drawSprite(0, 0, HEIGHT, WIDTH, paused_screen); + if (pause_timer % 10 <= 4) { + lcd.drawSpriteTransparent(20, 20, 9, 45, (int *)pause_sprite); + } + lcd.refresh(); + pause_timer++; + wait_ms(1000/40); + }; + } +} + +void GameEngine::draw_player(N5110 &lcd) +{ + lcd.drawSpriteTransparent(player.get_pos_x()-player.get_offset_x(), + player.get_pos_y()-player.get_offset_y(), + player.get_sprite_height(), + player.get_sprite_width(), + player.get_frame()); +} + +void GameEngine::draw_enemies(N5110 &lcd) +{ + for (int i = 0; i < MAX_ENEMIES; i++) { + if (room.valid_enemies[i]) { + lcd.drawSpriteTransparent(room.enemies[i]->get_pos_x()-room.enemies[i]->get_offset_x(), + room.enemies[i]->get_pos_y()-room.enemies[i]->get_offset_y(), + room.enemies[i]->get_sprite_height(), + room.enemies[i]->get_sprite_width(), + room.enemies[i]->get_frame()); + } + }; +} + +void GameEngine::draw_bullets(N5110 &lcd) +{ + for (int i = 0; i < bullets_max; i++) { + if (player.valid_bullets[i]) { + lcd.drawSpriteTransparent(player.bullets_array[i]->get_pos_x()-player.bullets_array[i]->get_offset_x(), + player.bullets_array[i]->get_pos_y()-player.bullets_array[i]->get_offset_y(), + player.bullets_array[i]->get_sprite_height(), + player.bullets_array[i]->get_sprite_width(), + player.bullets_array[i]->get_frame()); + } + }; +} + +void GameEngine::draw_health(N5110 &lcd) +{ + lcd.drawSpriteTransparent(0, + 0, + player.get_hearts_height(), + player.get_hearts_width(), + player.get_hearts_sprite()); +} \ No newline at end of file