James Cummins / Mbed 2 deprecated el17jnc

Dependencies:   mbed

Classic_Engine/ClassicEngine.cpp

Committer:
JamesCummins
Date:
2019-05-09
Revision:
38:a85bc227b907
Parent:
36:9f7463a65fe0
Child:
40:a1cdb6ab08af

File content as of revision 38:a85bc227b907:

#include "ClassicEngine.h"

//constructor
ClassicEngine::ClassicEngine(){
}

//destructor
ClassicEngine::~ClassicEngine(){
}

//initialiser
void ClassicEngine::init(Ball &ball, Map &map){
    _frames = 0;            //set frames counted to 0
    _ball_coord.x = 42;     //set ball to middle of screen
    _ball_coord.y = 24;
    _map_coord.x = 47;      //set map to the start area
    _map_coord.y = 25;
    ball.set_position(_ball_coord);
    map.set_map_display(_map_coord);
}

void ClassicEngine::classic_update(Ball &ball, FXOS8700CQ &accelerometer, Map &map){
    map.read_input(accelerometer, ball);
    map.update();                       //get map input from accelerometer and update region to display
    ball.set_position(_ball_coord);     //keep ball fixed to middle
    _frames++;                          //increment frames count for timer
    _map_coord = map.get_map_display();
    _abs_ball_pos.x = _ball_coord.x + _map_coord.x;     //update the ball's position in relation to the map
    _abs_ball_pos.y = _ball_coord.y + _map_coord.y;     //(even though it's fixed on the screen)
}

void ClassicEngine::classic_draw(N5110 &lcd, Map &map, Ball &ball){
    map.draw(lcd);      //draw map
    ball.draw(lcd);     //draw ball
}

bool ClassicEngine::finished(){
    bool finished = false;
    if(_abs_ball_pos.x > 402   &&       //these are the range of coords the ball
       _abs_ball_pos.x < 403   &&       //can have as it crosses the finish line
       _abs_ball_pos.y > 101   &&       //must be given as a range rather than an
       _abs_ball_pos.y < 141   ){       //exact number as .x and .y are floats so 
           finished = true;             //will never exactly equal 402
    }
    else{ finished = false; }
    printf("ball pos = %f , %f   |   finished = %d\n", _abs_ball_pos.x, _abs_ball_pos.y, finished);
    return finished;        //tell the game mode that the ball's reached the end of the course
}

void ClassicEngine::mode_complete(N5110 &lcd, Gamepad &gamepad, int fps){
    float time_taken;
    while(!(gamepad.check_event(gamepad.A_PRESSED))){       //check for user advancing
        time_taken = _frames / fps;     //calculate time taken from no. of frames that passed
        char buffer[6];
        sprintf(buffer, "%4.f", time_taken);        //write the time taken into a buffer
        lcd.clear();
        lcd.printString("You win!", 18, 1);         //win message
        lcd.printString("Your time:", 12, 3);
        lcd.printString(buffer, 18,4);              //print the time taken
        lcd.printChar('s',54,4);
        lcd.printString("(A = back)", 24, 5);
        lcd.refresh();
        wait(0.2);          //slower frame rate to reduce button bounce effects
    }
    write_high_scores(time_taken);      //check if high score, and update leaderboard if so
}

bool ClassicEngine::mode_failed(N5110 &lcd, Gamepad &gamepad, Ball &ball, Map &map){
    bool back_to_start_menu = false;        //bool to store whether restarting or going to main menu
    while(1){
              wait(0.2);
              lcd.clear();
              lcd.printString("Game over!", 12, 1);         //display potential options
              lcd.printString("Back = A", 18, 3);
              lcd.printString("Replay = B", 12, 4);
              lcd.refresh();
        if(gamepad.check_event(gamepad.A_PRESSED)){
            back_to_start_menu = true;          //return to start menu
            break; }                                    //use of break commands as while(!(a pressed || b pressed)) was buggy in run time
        if(gamepad.check_event(gamepad.B_PRESSED)){
            back_to_start_menu = false;         //restart
            break; }
    }
    return back_to_start_menu;
}

void ClassicEngine::read_high_scores(){
    FILE *fp;                                           //open file stream
    fp = fopen("/sd/classichighscores.txt", "r");       //open classic high scores file in read mode
    
    if(fp == NULL){
        printf("Error: Could not open file");           //check open
    } else {
        int i = 0;
        rewind(fp);         //go back to start of file
        
        while(fscanf(fp, "%d,%f", &_index_array[i], &_array_of_values[i]) != EOF){      //read into index and value arrays until end of file
            i++;        //increment which array row to read into
        }
        fclose(fp);     //close file stream
    }
}

void ClassicEngine::check_high_score(int time_taken){
    read_high_scores();
    for(int i = 4; i >= 0; i--){                        //algorithm to reorder high scores if new
        if(_array_of_values[i] > time_taken){           //high score achieve or discard if not
            _array_of_values[i+1] = _array_of_values[i];
            _array_of_values[i] = time_taken;           //note: must seed high scores with ascending numbers when file made for first time
        }
    }
}

void ClassicEngine::write_high_scores(int time_taken){
    check_high_score(time_taken);
    FILE *fp;                                       //open file stream
    fp = fopen("/sd/classichighscores.txt", "w");   //open classic high score file in write mode
    if(fp == NULL){
        printf("Error: Could not open file");       //check open
    } else {
        for(int i = 0; i < 5; i++){
            fprintf(fp, "%d, %f\n", _index_array[i], _array_of_values[i]);  //write 5 highest values of high score array into file
        }
        fclose(fp);     //close file stream
    }
}