ELEC2645 (2018/19) / Mbed 2 deprecated el17cd

Dependencies:   mbed

Game/Game.cpp

Committer:
el17cd
Date:
2019-04-04
Revision:
29:4a02f0bae202
Parent:
28:f8ff7c8c1627
Child:
30:91038c2afec7

File content as of revision 29:4a02f0bae202:

#include "Game.h"

Serial pc(USBTX, USBRX); // tx, rx

Game::Game(){
    noOfCubes = 25; //How many cubes are in the scene
    homeSelection = 0; //default selection for the home screen
    gamepad.init();
    renderer.init();
    resetScene();
    help = -1;
    input.x = 0;
    input.bCooldown = input.yCooldown = input.aCooldown = false;
}

void Game::resetScene(){
    for(int i = 0; i < noOfCubes; i++){ //Set initial position of all cubes
        cubeArray[i].translate(rand()%250-125, 0, 10+ i*5); //Position will be based on random integers
    }
}

int Game::readHighScore(){
//    filePointer = fopen("/sd/highscore.txt", "r");
    if (filePointer != NULL) {
        highScore = fscanf(filePointer, "%i");
    }
    else {
        highScore = 0;
    }
    return highScore;
    pc.printf("%i", highScore);
}

void Game::writeHighScore(int score){
 //   filePointer = fopen("/sd/highscore.txt", "w");
    if (filePointer != NULL) {
        fprintf(filePointer, "%i", score);
    }
}


void Game::run(){
    pc.printf("in");
    inHomeMenu = true;
    score = 0;
    deathMenuSelection = true;
    playing = true; //set game state to playing and death screen selection to 'restart'
    while(true) {
        processInput();
        renderer.clear();
        if(help > -1){
            helpScreen();
        }
        else if(inHomeMenu){
            homeScreen();
        }
        else{
            play();
        }
        renderer.refresh(); //refresh lcd
    }
}

void Game::play(){
    renderer.drawHorizon(input.x/15); //draw the horizon line
    
    for (int c = 0; c< noOfCubes; c++){  
        moveCubes(&cubeArray[c]); //translate cubes depending on joystick location and score
        cubeToBeRendered(&cubeArray[c], c); //add all cube faces to array to later be rendered
        checkDespawn(&cubeArray[c]); //check if any cubes are behind the perspective
        checkDeath(&cubeArray[c]); //check if any cubes are too close to user
    }
    renderer.drawAllFaces(faceArray, noOfCubes, input.x); //draw all faces added to the face array
    displayDeathMenu(); //display death menu if cube is too close to user
    addScore();
    renderer.printScore(score, 0, 0); //print score on top left of screen
}

void Game::checkDespawn(Cube *cube){ //checks if the cube is behind the perspective
    if (cube->despawn()){
        cube->resetPos(); //reset position to origin
        cube->translate(rand()%250-125,0,140); //translate cube to new far away position
    }
}

void Game::checkDeath(Cube *cube){ //Check whether the user has hit a cube
    if (cube->tooClose()){
        playing = false; //set state of game to not playing
        cube->resetPos();
        cube->translate(rand()%250-125,0,140); //reset and translate cube to back position
    }
}

void Game::cubeToBeRendered(Cube *cube, int cubeIndex){ //Adds all faces within the cube to an array of faces to be rendered
    for (int i = 0; i < 6; i++){
        faceArray[cubeIndex*6 + i] = cube->getFace(i);
    }
}


void Game::moveCubes(Cube *cube){ //animate cubes
    if(playing){
        if(score < 2000)
            cube->translate(-input.x*1.4f,0,-1-(float)score/1000); //move cubes closer to user and in x axis depending on joystick pos
        else{
            cube->translate(-input.x*1.4f,0,-3); //once max speed reached maintain constant z speed
        }
    }
    else{
        coord.x = 0; //if not playing (dead) prevent joystick moving anything
    }
}

void Game::displayDeathMenu() { //display restart or back to home menu
    if(!playing){
        if(score > highScore) {
            highScore = score;
            writeHighScore(highScore);
        }
        renderer.drawDeathScreen(deathMenuSelection, highScore); //draw death screen if game over
        deathButtonSelections(); //select menu option
    }

}

void Game::addScore(){ //increment score by 1 each frame
    if(playing){
        score++; //add score if still playing
    }
}

void Game::resetScore(){  //reset score to 0
    score = 0;
}

void Game::deathButtonSelections(){ //determine selection on death screen
        if(input.yButton){ //if y pressed highlight top option (restart)
            deathMenuSelection = true;
        }
        else if(input.aButton){ //if a pressed highlight bottom option (home menu)
            deathMenuSelection = false;
        }
        if (deathMenuSelection && input.bButton){ //if top option highlighted and b pressed then restart game
            playing = true;
            score = 0;
            resetScore();
            resetScene();
        }
        else if(!deathMenuSelection && input.bButton){ //if bottom option highlighted and b pressed then go to home screen
            resetScore();
            inHomeMenu = true;
        }
}

void Game::homeButtonSelections(){ //determine selection on home screen
        if(input.yButton && homeSelection > 0){ //if top option isnt highlighted and y pressed then move highlight up
            homeSelection--;
        }
        else if(input.aButton && homeSelection < 2){ //if bottom option isnt highlighted and a pressed then move highlight down
            homeSelection++;
        }
        if (input.bButton && homeSelection == 0){ //if top highlighted and b pressed then start game
            inHomeMenu = false;
        }
        else if(input.bButton && homeSelection == 1){ //if bottom highlighted and b pressed then exit game
            help = 0;
        }
        else if(input.bButton && homeSelection == 2){ //if bottom highlighted and b pressed then exit game
            renderer.turnOff();
            exit(0);
        }
}

void Game::homeScreen(){
    homeButtonSelections(); //determine selection on home screen
    if(help == -1) {
        renderer.drawHomeScreen(homeSelection); //draw home screen
    }
    else{
        helpScreen();
    }
}

void Game::helpScreen(){
    if (help < 2) {
        renderer.drawHelpScreen1();
        checkNextHelpScreen();
    }
    else if (help == 2) {
        renderer.drawHelpScreen2();   //execution starts at this case label
        checkNextHelpScreen();
    }
    else if (help == 3) {
        renderer.drawHelpScreen3();
        checkNextHelpScreen();
    }
    else if (help == 4) {
        help = -1;
    }
}

void Game::checkNextHelpScreen(){
    if(input.bButton){
        help ++;
                pc.printf("%i\r\n", help);
    }
}

void Game::processInput(){
    input.x = gamepad.get_coord().x;
    bool y = gamepad.check_event(Gamepad::Y_PRESSED);
    bool a = gamepad.check_event(Gamepad::A_PRESSED);
    bool b = gamepad.check_event(Gamepad::B_PRESSED);

    disableYButton(y);
    disableAButton(a);
    disableBButton(b);
}

void Game::disableYButton(bool y){
    if(!input.yCooldown && y){
        input.yCooldown = true;
        disableY.attach(this, &Game::enableY, 0.3);
        input.yButton = true;
    }
    else{
        input.yButton = false;
    }
}

void Game::disableAButton(bool a){
    if(!input.aCooldown && a){
        input.aCooldown = true;
        disableA.attach(this, &Game::enableA, 0.3);
        input.aButton = true;
    }
    else{
        input.aButton = false;
    }    
}

void Game::disableBButton(bool b){
    if(!input.bCooldown && b){
        input.bCooldown = true;
        disableB.attach(this, &Game::enableB, 0.3);
        input.bButton = true;
    }
    else{
        input.bButton = false;
    }
}

void Game::enableA(){
    disableA.detach();
    input.aCooldown = false;
}

void Game::enableB(){
    disableB.detach();
    input.bCooldown = false;
}

void Game::enableY(){
    disableY.detach();
    input.yCooldown = false;
}