Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed MotionSensor
main.cpp
- Committer:
- el17sm
- Date:
- 2019-05-09
- Revision:
- 49:3f83ed62d123
- Parent:
- 48:f7d9ae3e554d
- Child:
- 50:2c5cb92a5361
File content as of revision 49:3f83ed62d123:
/*
ELEC2645 Embedded Systems Project
School of Electronic & Electrical Engineering
University of Leeds
Name: Steven Mahasin
Username: el17sm
Student ID Number: 201192939
Date: 11/04/2019
*/
#include "main.h"
int main()
{
// Initialize
init();
while(1) { // Gameloop
boss_room_exist = false;
number_of_enemies_killed = 0;
total_time = 0;
title.main(lcd, gamepad, global_contrast);
srand(title.get_seed());
player = new Player(39, 27);
room_engine = new RoomEngine(global_contrast);
game_loop();
game_unload();
}
}
void init()
{
lcd.init();
lcd.setContrast(global_contrast);
gamepad.init();
for (int j = 0; j < MAX_ROOMS_MAP_Y; j++){
for (int i = 0; i < MAX_ROOMS_MAP_X; i++){
valid_rooms[j][i] = false;
}
}
}
void game_loop()
{
while(1) { // Floor Loop
boss_room_number = 5 + rand() % 4; // Boss room appears after travelling 5-8 rooms
boss_room_counter = 0;
while(1) { // Room Loop
room_entrance();
while(room_engine->check_player_room_position() == INSIDE) { // actions inside the Room
room_engine->read_input(gamepad);
room_engine->update(number_of_enemies_killed);
room_engine->render(lcd, gamepad);
minimap_detection();
total_time++;
if (player->get_hp() <= 0) {goto gameover;} // gameover if player health depleted
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
}
room_exit();
}
}
gameover : { game_over(); goto displaystats;}
winner : { win(); goto displaystats;}
displaystats : { display_stats();}
}
void room_entrance()
{
update_room_coords();
if (!valid_rooms[room_y][room_x]){generate_room();} // generate a new room if player enters a nonexistent room
room_engine->load(player, rooms[room_y][room_x]);
room_engine->entrance_scene(lcd, gamepad);
}
void room_exit()
{
room_engine->exit_scene(lcd, gamepad);
rooms[room_y][room_x]->unload();
player->delete_bullets();
room_engine->update_current_room();
}
void generate_room()
{
valid_rooms[room_y][room_x] = true;
if (boss_room_counter == 0) {
rooms[room_y][room_x] = new Room(0, 0);
rooms[room_y][room_x]->set_doorway(0, true);
} else {
rooms[room_y][room_x] = new Room(rand() % 4, 0);
if (boss_room_counter < boss_room_number) {no_of_doorways = 2 + (rand() % 100 < 10) + (rand() % 100 < 10);} // 20% chance of adding doorways
else {no_of_doorways = 0;}
while (count_doorways() < no_of_doorways) {
rooms[room_y][room_x]->set_doorway(rand() % 4, true); // Setting random doorways until number of desired doorways
}
update_definite_doorways();
for (int i = 0; i < 4; i++) {
if (cannot[i]){rooms[room_y][room_x]->set_doorway(i, false);}
if (have_to[i]){rooms[room_y][room_x]->set_doorway(i, true);}
}
if ((boss_room_counter >= boss_room_number) && (!boss_room_exist)) {
rooms[room_y][room_x]->set_boss_doorway(available_boss_room());
boss_room_exist = true;
}
}
boss_room_counter++;
}
void update_room_coords()
{
prev_room_x = room_x;
prev_room_y = room_y;
room_y = room_engine->get_room_y();
room_x = room_engine->get_room_x();
}
void minimap_detection()
{
while(gamepad.check_event(Gamepad::R_PRESSED)) {
lcd.clear();
for (int j = 0; j < MAX_ROOMS_MAP_Y; j++) {
for (int i = 0; i < MAX_ROOMS_MAP_X; i++) {
if (valid_rooms[j][i]) {
lcd.drawSprite(33 + (i-room_x)*20, 17 + (j-room_y)*15, 15, 20, (char *)minimap_sprite[0]);
if (rooms[j][i]->get_room_type() == 10) {
lcd.drawSprite(33 + (i-room_x)*20, 17 + (j-room_y)*15, 15, 20, (char *)minimap_sprite[2]);
} else if (rooms[j][i]->enemies_exist()) {
lcd.drawSprite(33 + (i-room_x)*20, 17 + (j-room_y)*15, 15, 20, (char *)minimap_sprite[1]);
}
if (rooms[j][i]->get_doorway(0)) {
lcd.drawLine(42 + (i-room_x)*20, 17 + (j-room_y)*15, 43 + (i-room_x)*20, 17 + (j-room_y)*15, 1);
}
if (rooms[j][i]->get_doorway(1)) {
lcd.drawLine(52 + (i-room_x)*20, 23 + (j-room_y)*15, 52 + (i-room_x)*20, 24 + (j-room_y)*15, 1);
}
if (rooms[j][i]->get_doorway(2)) {
lcd.drawLine(42 + (i-room_x)*20, 31 + (j-room_y)*15, 43 + (i-room_x)*20, 31 + (j-room_y)*15, 1);
}
if (rooms[j][i]->get_doorway(3)) {
lcd.drawLine(33 + (i-room_x)*20, 23 + (j-room_y)*15, 33 + (i-room_x)*20, 24 + (j-room_y)*15, 1);
}
}
}
}
lcd.drawSpriteTransparent(33, 17, 15, 20, (char *)minimap_sprite[3]);
lcd.refresh();
wait_ms(1000/40);
};
}
void game_over()
{
lcd.clear();
lcd.setContrast(global_contrast);
lcd.printString("Game Over", 0, 0);
}
void win()
{
lcd.clear();
lcd.setContrast(global_contrast);
lcd.printString("You won!", 0, 0);
}
void display_stats()
{
lcd.printString("Restart?", 0, 1);
lcd.printString("Enemies Killed:", 0, 2);
char kills[10];
sprintf(kills, "%d enemies", number_of_enemies_killed);
lcd.printString(kills, 0, 3);
lcd.printString("Time:", 0, 4);
char total_duration[10];
sprintf(total_duration, "%d seconds", (total_time/40));
lcd.printString(total_duration, 0, 5);
lcd.refresh();
while(gamepad.check_event(Gamepad::A_PRESSED)) {
}
wait(0.05);
while(!gamepad.check_event(Gamepad::A_PRESSED)) {
}
wait(0.05);
while(gamepad.check_event(Gamepad::A_PRESSED)) {
}
}
int available_boss_room()
{
if (!valid_rooms[room_y - 1][room_x]){
rooms[room_y][room_x]->set_doorway(0, true);
set_boss_room(room_y - 1, room_x, 0);
return 0;
} else if (!valid_rooms[room_y][room_x + 1]){
rooms[room_y][room_x]->set_doorway(1, true);
set_boss_room(room_y, room_x + 1, 1);
return 1;
} else if (!valid_rooms[room_y + 1][room_x]){
rooms[room_y][room_x]->set_doorway(2, true);
set_boss_room(room_y + 1, room_x, 2);
return 2;
} else if (!valid_rooms[room_y][room_x - 1]){
rooms[room_y][room_x]->set_doorway(3, true);
set_boss_room(room_y, room_x - 1, 3);
return 3; }
delete rooms[room_y - 1][room_x];
rooms[room_y][room_x]->set_doorway(3, true);
set_boss_room(room_y - 1, room_x, 0);
return 0;
}
void set_boss_room(int room_y, int room_x, int side)
{
valid_rooms[room_y][room_x] = true;
rooms[room_y][room_x] = new Room(0, 10);
rooms[room_y][room_x]->set_doorway(opposite(side), true);
if ((opposite(side) != 0) && (valid_rooms[room_y - 1][room_x])){
if (rooms[room_y - 1][room_x]->get_doorway(2)){
rooms[room_y - 1][room_x]->set_doorway(2, false);
}}
if ((opposite(side) != 1) && (valid_rooms[room_y][room_x + 1])){
if (rooms[room_y][room_x + 1]->get_doorway(3)){
rooms[room_y][room_x + 1]->set_doorway(3, false);
}}
if ((opposite(side) != 2) && (valid_rooms[room_y + 1][room_x])){
if (rooms[room_y + 1][room_x]->get_doorway(0)){
rooms[room_y + 1][room_x]->set_doorway(0, false);
}}
if ((opposite(side) != 3) && (valid_rooms[room_y][room_x - 1])){
if (rooms[room_y][room_x - 1]->get_doorway(1)){
rooms[room_y][room_x - 1]->set_doorway(1, false);
}}
}
void game_unload()
{
for (int i = 0; i < MAX_ROOMS_MAP_X; i++) {
for (int j = 0; j < MAX_ROOMS_MAP_Y; j++) {
if (valid_rooms[j][j]){
delete rooms[j][i];
valid_rooms[i][j] = false;
}
}
}
delete room_engine;
delete player;
}
// Functions
int opposite(int value)
{
if (value <= 1) {
return value + 2;
} else {
return value - 2;
}
}
int count_doorways() // counts number of exisisting doorways
{
int count = 0;
for (int i = 0; i < 4; i++){
if (rooms[room_y][room_x]->get_doorway(i)) {
count++;
}
}
return count;
}
void update_definite_doorways()
{
update_definite_doorways_up();
update_definite_doorways_right();
update_definite_doorways_down();
update_definite_doorways_left();
}
void update_definite_doorways_up()
{
if (room_y == 1) { // if room to be generated is on the border, then doorway cannot exist
cannot[0] = true;
have_to[0] = false;
} else if (valid_rooms[room_y - 1][room_x]){ // if room to be generated is on the border, then doorway cannot exist
if (rooms[room_y - 1][room_x]->get_doorway(2)){
have_to[0] = true;
cannot[0] = false;
} else {
have_to[0] = false;
cannot[0] = true;
}
} else {
have_to[0] = false;
cannot[0] = false;
}
}
void update_definite_doorways_right()
{
if (room_x == 10) {
cannot[1] = true;
have_to[1] = false;
} else if (valid_rooms[room_y][room_x + 1]){
if (rooms[room_y][room_x + 1]->get_doorway(3)){
have_to[1] = true;
cannot[1] = false;
} else {
have_to[1] = false;
cannot[1] = true;
}
} else {
have_to[1] = false;
cannot[1] = false;
}
}
void update_definite_doorways_down()
{
if (room_y == 10) {
cannot[2] = true;
have_to[2] = false;
} else if (valid_rooms[room_y + 1][room_x]){
if (rooms[room_y + 1][room_x]->get_doorway(0)){
have_to[2] = true;
cannot[2] = false;
} else {
have_to[2] = false;
cannot[2] = true;
}
} else {
have_to[2] = false;
cannot[2] = false;
}
}
void update_definite_doorways_left()
{
if (room_x == 1) {
cannot[3] = true;
have_to[3] = false;
} else if (valid_rooms[room_y][room_x - 1]){
if (rooms[room_y][room_x - 1]->get_doorway(1)){
have_to[3] = true;
cannot[3] = false;
} else {
have_to[3] = false;
cannot[3] = true;
}
} else {
have_to[3] = false;
cannot[3] = false;
}
}