ELEC2645 (2018/19) / Mbed 2 deprecated el17ajf

Dependencies:   mbed

Fork of el17ajf by Angus Findlay

Game/Game.cpp

Committer:
el17ajf
Date:
2019-04-24
Revision:
36:c854f1f51f43
Parent:
34:0bb0d010e755
Child:
39:e128071a95b0

File content as of revision 36:c854f1f51f43:

#include "Game.h"
#include "Graphics.h"
#include "Input.h"
#include "Engine.h"
#include "MenuManager.h"
#include "GameOverMenu.h"
#include "PausedMenu.h"
#include "Prefs.h"
#include "Math.h"

Game::Game(Difficulty difficulty) :
    score(0),
    next_tetromino_type(Tetromino::getRandomTetrominoType()),
    current_tetromino(
        Tetromino::getTetrominoOfType(Tetromino::getRandomTetrominoType())),
    frames(0),
    last_move_frame(0),
    start_x(Grid::GRID_WIDTH / 2 - 1),
    player_number(Prefs::getInstance()->getKey(Prefs::LAST_PLAYER)) {
    current_tetromino = current_tetromino.teleportedTo(start_x);
    switch (difficulty) {
        case EASY:
            move_frames = Engine::FPS / 6; // ~ 160ms
            score_for_row = 6;
            break;
        case MEDIUM:
            move_frames = Engine::FPS / 9; // ~ 110ms
            score_for_row = 8;
            break;
        case HARD:
            move_frames = Engine::FPS / 12; // ~ 80ms
            score_for_row = 10;
            break;
    }
    
    if (player_number == Prefs::EMPTY) {
        player_number = 1;
    } else {
        player_number += 1;
    }
}

Game::~Game() {}

void Game::update() {
    if (frames++ > last_move_frame + move_frames) {
        last_move_frame = frames;
        moveCurrentTetrominoDown();
    }
    
    if (Input::buttonHit(Input::LEFT)) {
        if (grid.isSpaceForTetromino(current_tetromino.movedLeft())) {
            current_tetromino = current_tetromino.movedLeft();
        }
    }
    if (Input::buttonHit(Input::RIGHT)) {
        if (grid.isSpaceForTetromino(current_tetromino.movedRight())) {
            current_tetromino = current_tetromino.movedRight();
        }
    }
    if (Input::buttonHit(Input::UP)) {
        if (grid.isSpaceForTetromino(current_tetromino.rotatedClockwise())) {
            current_tetromino = current_tetromino.rotatedClockwise();
        }
    }
    if (Input::buttonHit(Input::DOWN)) {
        dropCurrentTetromino();
    }
    if (Input::buttonHit(Input::START)) {
        Menus::MenuManager::add(new Menus::PausedMenu());
    }
}

void Game::addScore(int rows_cleared) {
    score += score_for_row * rows_cleared * rows_cleared;
    move_frames = Math::lerp(move_frames, 1, (double)score/9999);
    if (score > 9999) {
        score = 9999;
    }
}

void Game::moveCurrentTetrominoDown() {
    if (grid.isSpaceForTetromino(current_tetromino.movedDown())) {
        current_tetromino = current_tetromino.movedDown();
    } else {
        int rows_cleared = grid.placeTetromino(current_tetromino);
        if (rows_cleared != 0) {
            addScore(rows_cleared);
        }
        current_tetromino = Tetromino::getTetrominoOfType(next_tetromino_type);
        // centre it
        current_tetromino = current_tetromino.teleportedTo(start_x);
        if (!grid.isSpaceForTetromino(current_tetromino)) {
            // no space for tetromino, game over
            gameOver();
        }
        next_tetromino_type = Tetromino::getRandomTetrominoType();
    }
}

void Game::dropCurrentTetromino() {
    while (grid.isSpaceForTetromino(current_tetromino.movedDown())) {
        score += 1;
        current_tetromino = current_tetromino.movedDown();
    }
    moveCurrentTetrominoDown();
    Graphics::Game::shake(0, 3);
}

void Game::draw() {
    current_tetromino.draw();
    grid.draw();
}

void Game::gameOver() {
    Prefs::getInstance()->setKey(Prefs::LAST_PLAYER, player_number);
    Prefs::getInstance()->setKey(Prefs::LAST_SCORE, score);
    updateLeaderboard();
    Menus::MenuManager::add(new Menus::GameOverMenu());
}

void Game::updateLeaderboard() {
    for (int i = 0; i <= Prefs::HIGHSCORE3; i++) {
        if (score > Prefs::getInstance()->getKey((Prefs::Key)i)) {
            // move all scores down
            for (int j = Prefs::HIGHSCORE3 - 1; j >= i; j--) {
                Prefs::getInstance()->setKey(
                    (Prefs::Key)(j + 1),
                    Prefs::getInstance()->getKey((Prefs::Key)i)
                );
                Prefs::getInstance()->setKey(
                    (Prefs::Key)((j + 1) + 3),
                    Prefs::getInstance()->getKey((Prefs::Key)(i + 3))
                );
            }
            // set ith score to the current score
            Prefs::getInstance()->setKey((Prefs::Key)i, score);
            Prefs::getInstance()->setKey((Prefs::Key)(i + 3), player_number);
            break;
        }
    }
}