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

Dependencies:   mbed MotionSensor

main.cpp

Committer:
el17sm
Date:
2019-04-29
Revision:
26:abbc19edc5c1
Parent:
25:112cbcb0b4a7
Child:
27:a1b41626f57c

File content as of revision 26:abbc19edc5c1:

/*
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 "mbed.h"
#include "Gamepad.h"
#include "N5110.h"
#include "math.h"
#include "sprites.h"
#include "Entity.h"
#include "Player.h"
#include "Headless.h"
#include "Snake.h"

N5110 lcd(PTC9,PTC0,PTC7,PTD2,PTD1,PTC11);
Gamepad gamepad;

bool 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 y direction
float 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;
}

// 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 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;
}

int main()
{
    // initialize
    lcd.init();
    lcd.setContrast(0.45);
    gamepad.init();
    while(1) {
        Player player(39, 27);
        int no_of_enemies = 3;
        bool valid_enemies[no_of_enemies];
        for (int i = 0; i < no_of_enemies; i++) {
            valid_enemies[i] = false;
        }
        Entity *enemies[no_of_enemies];
        enemies[0] = new Headless(20, 20);
        valid_enemies[0] = true;
        enemies[1] = new Snake(20, 30);
        valid_enemies[1] = true;
        enemies[2] = new Snake(60, 30);
        valid_enemies[2] = true;

        while(1) {
            int pos_x = player.get_pos_x();
            int pos_y = player.get_pos_y();
            // Damage action
            for (int i = 0; i < no_of_enemies; i++) {
                if (valid_enemies[i]) {
                    if(entity_collision(player, *enemies[i])) {
                        player.take_damage(enemies[i]->get_attack());
                    }
                }
            };
            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 < no_of_enemies; j++) {
                            if (valid_enemies[j]) {
                                if(entity_collision(*player.bullets_array[i], *enemies[j])) {
                                    enemies[j]->take_damage(player.get_attack());
                                    player.valid_bullets[i] = false;
                                    delete player.bullets_array[i];
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            
            // Player Death
            if (player.death_check()) {
                goto gameover;
            }
            
            // Player Movement
            Vector2D mapped_coord = gamepad.get_mapped_coord();
            player.move(mapped_coord.x, mapped_coord.y);
            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));
            player.update_hearts();

            // Enemy Death
            for (int i = 0; i < no_of_enemies; i++) {
                if (valid_enemies[i]) {
                    if(enemies[i]->death_check()) {
                        valid_enemies[i] = false;
                        delete enemies[i];
                    }
                }
            }

            // Enemy Movement
            for (int i = 0; i < no_of_enemies; i++) {
                if (valid_enemies[i]) {
                    enemies[i]->update_prev_pos();
                    enemies[i]->move(pos_x, pos_y);
                }
            };
            for (int i = 0; i < bullets_max; i++) {
                if (player.valid_bullets[i]) {
                    player.bullets_array[i]->move(player.get_bullet_speed(), 0);
                }
            };
            for (int i = 0; i < no_of_enemies; i++) {
                if (valid_enemies[i]) {
                    enemies[i]->position_add_x(entity_move_check_x(enemies[i], enemies, no_of_enemies, i, valid_enemies));
                    enemies[i]->position_add_y(entity_move_check_y(enemies[i], enemies, no_of_enemies, i, valid_enemies));
                }
            };

            // Entity Collision Detection

            // MiniMap Screen Detection
            if(gamepad.check_event(Gamepad::BACK_PRESSED)) {
                wait(0.05);
                lcd.clear();
                while(gamepad.check_event(Gamepad::BACK_PRESSED)) {
                };
            };
            
            // Pause Detection
            if(gamepad.check_event(Gamepad::START_PRESSED)) {
                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(gamepad.check_event(Gamepad::START_PRESSED)) {
                    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(!gamepad.check_event(Gamepad::START_PRESSED)) {
                    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(gamepad.check_event(Gamepad::START_PRESSED)) {
                    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);
                };
            }


            // screen update
            lcd.clear();
            lcd.drawSprite(0,0,screen_height,screen_width,(int *)level_map[1]);
            lcd.drawSpriteTransparent(pos_x-player.get_offset_x(),
                                      pos_y-player.get_offset_y(),
                                      player.get_sprite_height(),
                                      player.get_sprite_width(),
                                      player.get_frame());
            for (int i = 0; i < no_of_enemies; i++) {
                if (valid_enemies[i]) {
                    lcd.drawSpriteTransparent(enemies[i]->get_pos_x()-enemies[i]->get_offset_x(),
                                              enemies[i]->get_pos_y()-enemies[i]->get_offset_y(),
                                              enemies[i]->get_sprite_height(),
                                              enemies[i]->get_sprite_width(),
                                              enemies[i]->get_frame());
                }
            };
            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());
                }
            };
            if (gamepad.check_event(Gamepad::L_PRESSED)) {
                lcd.drawSpriteTransparent(0,
                                          0,
                                          player.get_hearts_height(),
                                          player.get_hearts_width(),
                                          player.get_hearts_sprite());
            }
            lcd.refresh();
            wait_ms(1000/40); // setting FPS
        }
gameover: {
            lcd.clear();
            lcd.printString("Game Over", 0, 0);
            lcd.printString("Retry?", 0, 1);
            lcd.refresh();
            player.~Player();
            for (int i = 0; i < no_of_enemies; i++) {
                if (valid_enemies[i]) {
                    delete enemies[i];
                }
            };
            wait(0.05);
            while(!gamepad.check_event(Gamepad::A_PRESSED)) {
            };
            wait(0.05);
            while(gamepad.check_event(Gamepad::A_PRESSED)) {
            }
        }
    }
}

void render(){
    lcd.clear();
    lcd.refresh();
    wait_ms(1000/40); // setting FPS
}