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:
Mon Apr 29 02:45:17 2019 +0000
Revision:
26:abbc19edc5c1
Parent:
25:112cbcb0b4a7
Child:
27:a1b41626f57c
RoomEngine done, no test yet, Room h partial done;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
el17sm 0:8e92b66a0755 1 /*
el17sm 0:8e92b66a0755 2 ELEC2645 Embedded Systems Project
el17sm 0:8e92b66a0755 3 School of Electronic & Electrical Engineering
el17sm 0:8e92b66a0755 4 University of Leeds
el17sm 0:8e92b66a0755 5 Name: Steven Mahasin
el17sm 0:8e92b66a0755 6 Username: el17sm
el17sm 0:8e92b66a0755 7 Student ID Number: 201192939
el17sm 0:8e92b66a0755 8 Date: 11/04/2019
el17sm 1:1fa7ecca8dfb 9 */
el17sm 1:1fa7ecca8dfb 10
el17sm 7:4aaa37a711a1 11 #include "mbed.h"
el17sm 7:4aaa37a711a1 12 #include "Gamepad.h"
el17sm 7:4aaa37a711a1 13 #include "N5110.h"
el17sm 7:4aaa37a711a1 14 #include "math.h"
el17sm 7:4aaa37a711a1 15 #include "sprites.h"
el17sm 7:4aaa37a711a1 16 #include "Entity.h"
el17sm 7:4aaa37a711a1 17 #include "Player.h"
el17sm 10:1a3499f6b583 18 #include "Headless.h"
el17sm 17:99e533f7f2fb 19 #include "Snake.h"
el17sm 7:4aaa37a711a1 20
el17sm 7:4aaa37a711a1 21 N5110 lcd(PTC9,PTC0,PTC7,PTD2,PTD1,PTC11);
el17sm 7:4aaa37a711a1 22 Gamepad gamepad;
el17sm 7:4aaa37a711a1 23
el17sm 22:7abf4581bc9b 24 bool entity_collision(Entity &a, Entity &b) // returns true if the two entity hitboxes collide
el17sm 22:7abf4581bc9b 25 {
el17sm 11:63e54f6e7939 26 if (((b.get_pos_x() <= a.get_pos_x()) && (a.get_pos_x() <= b.get_pos_x() + b.get_hitbox_width() - 1)) ||
el17sm 22:7abf4581bc9b 27 ((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))) {
el17sm 11:63e54f6e7939 28 if (((b.get_pos_y() <= a.get_pos_y()) && (a.get_pos_y() <= b.get_pos_y() + b.get_hitbox_height() - 1)) ||
el17sm 22:7abf4581bc9b 29 ((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))) {
el17sm 10:1a3499f6b583 30 return true;
el17sm 22:7abf4581bc9b 31 }
el17sm 10:1a3499f6b583 32 }
el17sm 24:26369d92a06a 33 return 0;
el17sm 10:1a3499f6b583 34 }
el17sm 10:1a3499f6b583 35
el17sm 12:a1c1991835ca 36 // returns true if the hitbox of "entity a" collides with any hitboxes of enttities within "array" as "entity a" moves on the y direction
el17sm 24:26369d92a06a 37 float entity_move_check_y(Entity *a, Entity *array[], int no_of_enemies, int current_entity, bool valid_enemies[])
el17sm 22:7abf4581bc9b 38 {
el17sm 22:7abf4581bc9b 39 for (int i = 0; i < no_of_enemies; i++) {
el17sm 22:7abf4581bc9b 40 if (valid_enemies[i]) {
el17sm 22:7abf4581bc9b 41 if(i != current_entity) {
el17sm 13:d04a6caba40d 42 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)) ||
el17sm 22:7abf4581bc9b 43 ((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 13:d04a6caba40d 44 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 22:7abf4581bc9b 45 ((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 24:26369d92a06a 46 return (2*((a->get_pos_y() > array[i]->get_prev_pos_y()) - 0.5));
el17sm 13:d04a6caba40d 47 }
el17sm 12:a1c1991835ca 48 }
el17sm 11:63e54f6e7939 49 }
el17sm 11:63e54f6e7939 50 }
el17sm 11:63e54f6e7939 51 }
el17sm 24:26369d92a06a 52 return 0;
el17sm 11:63e54f6e7939 53 }
el17sm 11:63e54f6e7939 54
el17sm 12:a1c1991835ca 55 // returns true if the hitbox of "entity a" collides with any hitboxes of enttities within "array" as "entity a" moves on the x direction
el17sm 24:26369d92a06a 56 float entity_move_check_x(Entity *a, Entity *array[], int no_of_enemies, int current_entity, bool valid_enemies[])
el17sm 22:7abf4581bc9b 57 {
el17sm 22:7abf4581bc9b 58 for (int i = 0; i < no_of_enemies; i++) {
el17sm 22:7abf4581bc9b 59 if (valid_enemies[i]) {
el17sm 22:7abf4581bc9b 60 if(i != current_entity) {
el17sm 13:d04a6caba40d 61 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)) ||
el17sm 22:7abf4581bc9b 62 ((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 13:d04a6caba40d 63 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 22:7abf4581bc9b 64 ((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 24:26369d92a06a 65 return (2*((a->get_pos_x() > array[i]->get_prev_pos_x()) - 0.5));
el17sm 22:7abf4581bc9b 66 }
el17sm 13:d04a6caba40d 67 }
el17sm 11:63e54f6e7939 68 }
el17sm 11:63e54f6e7939 69 }
el17sm 11:63e54f6e7939 70 }
el17sm 24:26369d92a06a 71 return 0;
el17sm 11:63e54f6e7939 72 }
el17sm 11:63e54f6e7939 73
el17sm 1:1fa7ecca8dfb 74 int main()
el17sm 1:1fa7ecca8dfb 75 {
el17sm 26:abbc19edc5c1 76 // initialize
el17sm 1:1fa7ecca8dfb 77 lcd.init();
el17sm 2:dbfff27a8a94 78 lcd.setContrast(0.45);
el17sm 3:359a49bace1b 79 gamepad.init();
el17sm 22:7abf4581bc9b 80 while(1) {
el17sm 10:1a3499f6b583 81 Player player(39, 27);
el17sm 12:a1c1991835ca 82 int no_of_enemies = 3;
el17sm 13:d04a6caba40d 83 bool valid_enemies[no_of_enemies];
el17sm 22:7abf4581bc9b 84 for (int i = 0; i < no_of_enemies; i++) {
el17sm 22:7abf4581bc9b 85 valid_enemies[i] = false;
el17sm 22:7abf4581bc9b 86 }
el17sm 11:63e54f6e7939 87 Entity *enemies[no_of_enemies];
el17sm 17:99e533f7f2fb 88 enemies[0] = new Headless(20, 20);
el17sm 17:99e533f7f2fb 89 valid_enemies[0] = true;
el17sm 17:99e533f7f2fb 90 enemies[1] = new Snake(20, 30);
el17sm 17:99e533f7f2fb 91 valid_enemies[1] = true;
el17sm 23:5a8f75e93508 92 enemies[2] = new Snake(60, 30);
el17sm 23:5a8f75e93508 93 valid_enemies[2] = true;
el17sm 22:7abf4581bc9b 94
el17sm 22:7abf4581bc9b 95 while(1) {
el17sm 11:63e54f6e7939 96 int pos_x = player.get_pos_x();
el17sm 11:63e54f6e7939 97 int pos_y = player.get_pos_y();
el17sm 11:63e54f6e7939 98 // Damage action
el17sm 22:7abf4581bc9b 99 for (int i = 0; i < no_of_enemies; i++) {
el17sm 22:7abf4581bc9b 100 if (valid_enemies[i]) {
el17sm 22:7abf4581bc9b 101 if(entity_collision(player, *enemies[i])) {
el17sm 23:5a8f75e93508 102 player.take_damage(enemies[i]->get_attack());
el17sm 13:d04a6caba40d 103 }
el17sm 13:d04a6caba40d 104 }
el17sm 13:d04a6caba40d 105 };
el17sm 22:7abf4581bc9b 106 for (int i = 0; i < bullets_max; i++) {
el17sm 22:7abf4581bc9b 107 if (player.valid_bullets[i]) {
el17sm 22:7abf4581bc9b 108 if (player.bullets_array[i]->out_of_bounds_check()) {
el17sm 22:7abf4581bc9b 109 player.valid_bullets[i] = false;
el17sm 22:7abf4581bc9b 110 delete player.bullets_array[i];
el17sm 22:7abf4581bc9b 111 } else {
el17sm 22:7abf4581bc9b 112 for (int j = 0; j < no_of_enemies; j++) {
el17sm 22:7abf4581bc9b 113 if (valid_enemies[j]) {
el17sm 22:7abf4581bc9b 114 if(entity_collision(*player.bullets_array[i], *enemies[j])) {
el17sm 22:7abf4581bc9b 115 enemies[j]->take_damage(player.get_attack());
el17sm 22:7abf4581bc9b 116 player.valid_bullets[i] = false;
el17sm 22:7abf4581bc9b 117 delete player.bullets_array[i];
el17sm 22:7abf4581bc9b 118 break;
el17sm 22:7abf4581bc9b 119 }
el17sm 13:d04a6caba40d 120 }
el17sm 13:d04a6caba40d 121 }
el17sm 22:7abf4581bc9b 122 }
el17sm 11:63e54f6e7939 123 }
el17sm 22:7abf4581bc9b 124 }
el17sm 23:5a8f75e93508 125
el17sm 23:5a8f75e93508 126 // Player Death
el17sm 23:5a8f75e93508 127 if (player.death_check()) {
el17sm 23:5a8f75e93508 128 goto gameover;
el17sm 23:5a8f75e93508 129 }
el17sm 23:5a8f75e93508 130
el17sm 10:1a3499f6b583 131 // Player Movement
el17sm 10:1a3499f6b583 132 Vector2D mapped_coord = gamepad.get_mapped_coord();
el17sm 10:1a3499f6b583 133 player.move(mapped_coord.x, mapped_coord.y);
el17sm 10:1a3499f6b583 134 player.buttons(gamepad.check_event(Gamepad::A_PRESSED), gamepad.check_event(Gamepad::B_PRESSED), gamepad.check_event(Gamepad::Y_PRESSED), gamepad.check_event(Gamepad::X_PRESSED));
el17sm 23:5a8f75e93508 135 player.update_hearts();
el17sm 22:7abf4581bc9b 136
el17sm 14:3361879490b2 137 // Enemy Death
el17sm 22:7abf4581bc9b 138 for (int i = 0; i < no_of_enemies; i++) {
el17sm 22:7abf4581bc9b 139 if (valid_enemies[i]) {
el17sm 22:7abf4581bc9b 140 if(enemies[i]->death_check()) {
el17sm 22:7abf4581bc9b 141 valid_enemies[i] = false;
el17sm 22:7abf4581bc9b 142 delete enemies[i];
el17sm 22:7abf4581bc9b 143 }
el17sm 14:3361879490b2 144 }
el17sm 14:3361879490b2 145 }
el17sm 22:7abf4581bc9b 146
el17sm 10:1a3499f6b583 147 // Enemy Movement
el17sm 22:7abf4581bc9b 148 for (int i = 0; i < no_of_enemies; i++) {
el17sm 22:7abf4581bc9b 149 if (valid_enemies[i]) {
el17sm 13:d04a6caba40d 150 enemies[i]->update_prev_pos();
el17sm 13:d04a6caba40d 151 enemies[i]->move(pos_x, pos_y);
el17sm 13:d04a6caba40d 152 }
el17sm 11:63e54f6e7939 153 };
el17sm 22:7abf4581bc9b 154 for (int i = 0; i < bullets_max; i++) {
el17sm 22:7abf4581bc9b 155 if (player.valid_bullets[i]) {
el17sm 22:7abf4581bc9b 156 player.bullets_array[i]->move(player.get_bullet_speed(), 0);
el17sm 14:3361879490b2 157 }
el17sm 14:3361879490b2 158 };
el17sm 22:7abf4581bc9b 159 for (int i = 0; i < no_of_enemies; i++) {
el17sm 22:7abf4581bc9b 160 if (valid_enemies[i]) {
el17sm 24:26369d92a06a 161 enemies[i]->position_add_x(entity_move_check_x(enemies[i], enemies, no_of_enemies, i, valid_enemies));
el17sm 24:26369d92a06a 162 enemies[i]->position_add_y(entity_move_check_y(enemies[i], enemies, no_of_enemies, i, valid_enemies));
el17sm 13:d04a6caba40d 163 }
el17sm 11:63e54f6e7939 164 };
el17sm 22:7abf4581bc9b 165
el17sm 10:1a3499f6b583 166 // Entity Collision Detection
el17sm 22:7abf4581bc9b 167
el17sm 10:1a3499f6b583 168 // MiniMap Screen Detection
el17sm 26:abbc19edc5c1 169 if(gamepad.check_event(Gamepad::BACK_PRESSED)) {
el17sm 26:abbc19edc5c1 170 wait(0.05);
el17sm 26:abbc19edc5c1 171 lcd.clear();
el17sm 26:abbc19edc5c1 172 while(gamepad.check_event(Gamepad::BACK_PRESSED)) {
el17sm 26:abbc19edc5c1 173 };
el17sm 26:abbc19edc5c1 174 };
el17sm 26:abbc19edc5c1 175
el17sm 10:1a3499f6b583 176 // Pause Detection
el17sm 22:7abf4581bc9b 177 if(gamepad.check_event(Gamepad::START_PRESSED)) {
el17sm 25:112cbcb0b4a7 178 lcd.drawSpriteTransparent(0,
el17sm 25:112cbcb0b4a7 179 0,
el17sm 25:112cbcb0b4a7 180 player.get_hearts_height(),
el17sm 25:112cbcb0b4a7 181 player.get_hearts_width(),
el17sm 25:112cbcb0b4a7 182 player.get_hearts_sprite());
el17sm 25:112cbcb0b4a7 183 int * paused_screen = lcd.readScreen();
el17sm 25:112cbcb0b4a7 184 int pause_timer = 2;
el17sm 25:112cbcb0b4a7 185 lcd.drawSpriteTransparent(20, 20, 9, 45, (int *)pause_sprite);
el17sm 10:1a3499f6b583 186 wait(0.05);
el17sm 22:7abf4581bc9b 187 while(gamepad.check_event(Gamepad::START_PRESSED)) {
el17sm 25:112cbcb0b4a7 188 lcd.clear();
el17sm 25:112cbcb0b4a7 189 lcd.drawSprite(0, 0, HEIGHT, WIDTH, paused_screen);
el17sm 25:112cbcb0b4a7 190 if (pause_timer % 10 <= 4) {
el17sm 25:112cbcb0b4a7 191 lcd.drawSpriteTransparent(20, 20, 9, 45, (int *)pause_sprite);
el17sm 25:112cbcb0b4a7 192 }
el17sm 25:112cbcb0b4a7 193 lcd.refresh();
el17sm 25:112cbcb0b4a7 194 pause_timer++;
el17sm 25:112cbcb0b4a7 195 wait_ms(1000/40);
el17sm 10:1a3499f6b583 196 };
el17sm 10:1a3499f6b583 197 wait(0.05);
el17sm 25:112cbcb0b4a7 198 pause_timer += 2;
el17sm 22:7abf4581bc9b 199 while(!gamepad.check_event(Gamepad::START_PRESSED)) {
el17sm 25:112cbcb0b4a7 200 lcd.clear();
el17sm 25:112cbcb0b4a7 201 lcd.drawSprite(0, 0, HEIGHT, WIDTH, paused_screen);
el17sm 25:112cbcb0b4a7 202 if (pause_timer % 10 <= 4) {
el17sm 25:112cbcb0b4a7 203 lcd.drawSpriteTransparent(20, 20, 9, 45, (int *)pause_sprite);
el17sm 25:112cbcb0b4a7 204 }
el17sm 25:112cbcb0b4a7 205 lcd.refresh();
el17sm 25:112cbcb0b4a7 206 pause_timer++;
el17sm 25:112cbcb0b4a7 207 wait_ms(1000/40);
el17sm 10:1a3499f6b583 208 };
el17sm 10:1a3499f6b583 209 wait(0.05);
el17sm 25:112cbcb0b4a7 210 pause_timer += 2;
el17sm 22:7abf4581bc9b 211 while(gamepad.check_event(Gamepad::START_PRESSED)) {
el17sm 25:112cbcb0b4a7 212 lcd.clear();
el17sm 25:112cbcb0b4a7 213 lcd.drawSprite(0, 0, HEIGHT, WIDTH, paused_screen);
el17sm 25:112cbcb0b4a7 214 if (pause_timer % 10 <= 4) {
el17sm 25:112cbcb0b4a7 215 lcd.drawSpriteTransparent(20, 20, 9, 45, (int *)pause_sprite);
el17sm 25:112cbcb0b4a7 216 }
el17sm 25:112cbcb0b4a7 217 lcd.refresh();
el17sm 25:112cbcb0b4a7 218 pause_timer++;
el17sm 25:112cbcb0b4a7 219 wait_ms(1000/40);
el17sm 10:1a3499f6b583 220 };
el17sm 10:1a3499f6b583 221 }
el17sm 22:7abf4581bc9b 222
el17sm 22:7abf4581bc9b 223
el17sm 10:1a3499f6b583 224 // screen update
el17sm 10:1a3499f6b583 225 lcd.clear();
el17sm 10:1a3499f6b583 226 lcd.drawSprite(0,0,screen_height,screen_width,(int *)level_map[1]);
el17sm 11:63e54f6e7939 227 lcd.drawSpriteTransparent(pos_x-player.get_offset_x(),
el17sm 11:63e54f6e7939 228 pos_y-player.get_offset_y(),
el17sm 10:1a3499f6b583 229 player.get_sprite_height(),
el17sm 10:1a3499f6b583 230 player.get_sprite_width(),
el17sm 12:a1c1991835ca 231 player.get_frame());
el17sm 22:7abf4581bc9b 232 for (int i = 0; i < no_of_enemies; i++) {
el17sm 22:7abf4581bc9b 233 if (valid_enemies[i]) {
el17sm 13:d04a6caba40d 234 lcd.drawSpriteTransparent(enemies[i]->get_pos_x()-enemies[i]->get_offset_x(),
el17sm 13:d04a6caba40d 235 enemies[i]->get_pos_y()-enemies[i]->get_offset_y(),
el17sm 13:d04a6caba40d 236 enemies[i]->get_sprite_height(),
el17sm 13:d04a6caba40d 237 enemies[i]->get_sprite_width(),
el17sm 13:d04a6caba40d 238 enemies[i]->get_frame());
el17sm 13:d04a6caba40d 239 }
el17sm 11:63e54f6e7939 240 };
el17sm 22:7abf4581bc9b 241 for (int i = 0; i < bullets_max; i++) {
el17sm 22:7abf4581bc9b 242 if (player.valid_bullets[i]) {
el17sm 13:d04a6caba40d 243 lcd.drawSpriteTransparent(player.bullets_array[i]->get_pos_x()-player.bullets_array[i]->get_offset_x(),
el17sm 13:d04a6caba40d 244 player.bullets_array[i]->get_pos_y()-player.bullets_array[i]->get_offset_y(),
el17sm 13:d04a6caba40d 245 player.bullets_array[i]->get_sprite_height(),
el17sm 13:d04a6caba40d 246 player.bullets_array[i]->get_sprite_width(),
el17sm 13:d04a6caba40d 247 player.bullets_array[i]->get_frame());
el17sm 13:d04a6caba40d 248 }
el17sm 13:d04a6caba40d 249 };
el17sm 23:5a8f75e93508 250 if (gamepad.check_event(Gamepad::L_PRESSED)) {
el17sm 23:5a8f75e93508 251 lcd.drawSpriteTransparent(0,
el17sm 23:5a8f75e93508 252 0,
el17sm 23:5a8f75e93508 253 player.get_hearts_height(),
el17sm 23:5a8f75e93508 254 player.get_hearts_width(),
el17sm 23:5a8f75e93508 255 player.get_hearts_sprite());
el17sm 23:5a8f75e93508 256 }
el17sm 10:1a3499f6b583 257 lcd.refresh();
el17sm 23:5a8f75e93508 258 wait_ms(1000/40); // setting FPS
el17sm 10:1a3499f6b583 259 }
el17sm 22:7abf4581bc9b 260 gameover: {
el17sm 11:63e54f6e7939 261 lcd.clear();
el17sm 11:63e54f6e7939 262 lcd.printString("Game Over", 0, 0);
el17sm 11:63e54f6e7939 263 lcd.printString("Retry?", 0, 1);
el17sm 11:63e54f6e7939 264 lcd.refresh();
el17sm 11:63e54f6e7939 265 player.~Player();
el17sm 22:7abf4581bc9b 266 for (int i = 0; i < no_of_enemies; i++) {
el17sm 22:7abf4581bc9b 267 if (valid_enemies[i]) {
el17sm 22:7abf4581bc9b 268 delete enemies[i];
el17sm 22:7abf4581bc9b 269 }
el17sm 11:63e54f6e7939 270 };
el17sm 11:63e54f6e7939 271 wait(0.05);
el17sm 22:7abf4581bc9b 272 while(!gamepad.check_event(Gamepad::A_PRESSED)) {
el17sm 11:63e54f6e7939 273 };
el17sm 11:63e54f6e7939 274 wait(0.05);
el17sm 22:7abf4581bc9b 275 while(gamepad.check_event(Gamepad::A_PRESSED)) {
el17sm 22:7abf4581bc9b 276 }
el17sm 16:ddb203a74dfc 277 }
el17sm 22:7abf4581bc9b 278 }
el17sm 26:abbc19edc5c1 279 }
el17sm 26:abbc19edc5c1 280
el17sm 26:abbc19edc5c1 281 void render(){
el17sm 26:abbc19edc5c1 282 lcd.clear();
el17sm 26:abbc19edc5c1 283 lcd.refresh();
el17sm 26:abbc19edc5c1 284 wait_ms(1000/40); // setting FPS
el17sm 10:1a3499f6b583 285 }