ELEC2645 (2017/18) / Mbed OS el16ajm

main.cpp

Committer:
Andrew_M
Date:
2018-05-08
Revision:
15:130900e5c268
Parent:
14:a57a40ff9430
Child:
16:4d329ce7b156

File content as of revision 15:130900e5c268:

/*
ELEC2645 Embedded Systems Project
School of Electronic & Electrical Engineering
University of Leeds
Name: Andrew Moore
Username: el16ajm
Student ID Number: 201042893
Date:
*/

/** The Main class
* @brief Sends and recives data from the Menu and Engine classes, alters the refresh rate and calls all drawing from other classes
* @author Andrew J. Moore
* @date May, 2018
*/

#include "mbed.h"
#include "Gamepad.h"
#include "N5110.h"
#include "Engine.h"
#include "Menu.h"

/////////////// structs /////////////////
struct UserInput {
    Direction d;
};

/////////////// objects ///////////////
N5110 lcd(PTC9,PTC0,PTC7,PTD2,PTD1,PTC11);
Gamepad pad;
Engine gameEngine;
Menu mainMenu;

///////////// prototypes ///////////////
/** Initialization function */
void init();

/** Initialization function */
void update_game(UserInput input);

/** Draws the game onto the LCD */
void renderGame();

/** Draws the menu onto the LCD */
void renderMenu();

/** Draws the welcome screen onto the LCD */
void welcome();

/** Draws the transition screen onto the LCD */
void transition();

/** Resets game and menu logic once a game over state has been reached */
void reset();

/** Sets the difficulty/refresh rate */
float setDif();

///////////// functions ////////////////
int main()
{
    init();
    welcome();

    transition();

    // game loop - read input, update the game state and render the display
    while (1) {
        if (!mainMenu.started()) { //menu logic and rendering
            mainMenu.read_input(pad);
            mainMenu.update();
            gameEngine.setLvl(mainMenu.getLvl());
            renderMenu();
        } else if (gameEngine.getGameOver()) { //resets the game once a game over state has been reached
            gameEngine.gameOverScreen(lcd);
            reset();
        } else { //game logic and rendering
            gameEngine.read_input(pad);
            gameEngine.update(pad);
            renderGame();
        }
    }
}

void welcome()
{
    lcd.printString("     Snake!    ",0,1);
    lcd.printString("  Press Start ",0,4);
    lcd.refresh();

    // wait flashing LEDs until start button is pressed
    while ( pad.check_event(Gamepad::START_PRESSED) == false) {
        pad.leds_on();
        wait(0.1);
        pad.leds_off();
        wait(0.1);
    }
    wait(0.1);

}

void init()
{
    // need to initialise LCD and Gamepad
    gameEngine.init();
    lcd.init();
    pad.init();
    mainMenu.init();

}

void reset()
{
    mainMenu.init();        //resets both the mainMenu and gameEngine
    gameEngine.init();      //the gameEngine will reset the food and the snake in the process
}

void renderGame()
{
    // clear screen, re-draw and refresh
    lcd.clear();
    gameEngine.draw(lcd);
    lcd.refresh();
    wait(setDif()); //adaptive fps depending on difficulty
}

void renderMenu()
{
    // clear screen, re-draw and refresh
    lcd.clear();
    mainMenu.draw(lcd);
    lcd.refresh();
    wait(1.0f/8); //fixed at 8 fps
}

void transition()
{
    //transition animation between modes to reduce 'ghosting' of inputs
    
    for (int i = 0; i <= 11; i++) {                 //max values for i and j were chosen as the screen is 84x44 and the sqaures being drawn are 4x4
        for (int j = 0; j <= 21; j++) {
            lcd.drawRect(j*4,i*4,4,4,FILL_BLACK);   //covers the entire screen in 4x4 squares
            wait(0.005);                            //waits a small amount of time to allow the screen to keep up
            lcd.refresh();
        }
    }

}

float setDif()
{
    int _dif = mainMenu.getDif();

    if (_dif == 1) {                         //Low difficulty
        return 1.0f/4;
    } else if (_dif == 2) {                  //Medium difficulty
        return 1.0f/8;
    } else if (_dif == 3) {                  //Hard difficulty
        return 1.0f/12;
    } else {                                 //Adaptive difficulty
        float _delta = gameEngine.getScore(); 
        if (_delta < 25) {                   //Limits FPS to 25
            return ((1.0f/(_delta + 1)));    //changes the fps depending on score
        } else {
            return (1.0f/25);
        }
    }
}