Class used to run the maze game loop.

MazeEngine.cpp

Committer:
el15mh
Date:
2017-05-04
Revision:
5:3635319c64b8
Parent:
4:93fd2f3bd0de

File content as of revision 5:3635319c64b8:

#include "MazeEngine.h"

/**
 *  @details - constructor
 */
MazeEngine::MazeEngine()
{
    
}

/**
 *  @details - constructor
 */
MazeEngine::~MazeEngine()
{
    
}

/**
 *  @details - Initialises the game with specified paramters
 */
void MazeEngine::init(int mazeIndex,
                      int x,
                      int y,
                      int radius,
                      bool control,
                      bool colour)
{
    // maze parameters
    _mazeIndex = mazeIndex;
    
    // method of controlling
    _control = control;
    // _control = false;   // set as false just for debugging
    
    // style of ball
    _colour = colour;
    
    // ball parameters
    _radius = radius;
    _x = x;
    _y = y;
    
    // initialise ball & maze with parameters
    _ball.init(_x, _y, _radius, _colour);
    _maze.init(_mazeIndex);
}

/**
 *  @details - Reads input from chosen device
 */
void MazeEngine::readInput(Gamepad &pad, FXOS8700CQ &device)
{
    if (_control){  // if control is true (default), input comes from joystick
        readJoystickInput(pad);
    }
    else {  // if control is false, input comes from accelerometer
        readAccelerometer(device);
    }
}

/**
 *  @details - Reads joystick input
 */
void MazeEngine::readJoystickInput(Gamepad &pad)
{
    // position is a 2D struct for (x,y)
    position = pad.get_mapped_coord();
    
    // printf("Joystick inputs: %.2f, %.2f \n", position.x, position.y);
}

/**
 *  @details - Reads accelerometer input
 */
void MazeEngine::readAccelerometer(FXOS8700CQ &device)
{
    // acquire values from device
    Data values = device.get_values();
    
    // values are between 0 and 90°
    float pitch = device.getPitchAngle();
    float roll = device.getRollAngle();
    
    position.x = pitch / -60;    // divide by 60 for increase sensitivity
    position.y = roll / -60;
}

/**
 *  @details - Checks for wall collisions
 */
void MazeEngine::checkWallCollision(N5110 &lcd)
{
    // acquire position of ball
    // if position on each side of ball is a pixel
    // block movement in that direction
    
    Vector2D _position = _ball.getPosition();
    Vector2D _velocity = _ball.getVelocity();
        
    // printf("position = (%f, %f) \n", _position.x, _position.y);
    
    int leftSide = int(_position.x - _radius);
    int rightSide = int(_position.x + _radius);
    int topSide = int(_position.y - _radius);
    int lowerSide = int (_position.y + _radius);
    
    // check position of ball
    // if distance between outermost pixel and centre != original distance
    // there must be a pixel in adjacent position
    if (leftSide + _mazeArray[leftSide - 1][int(_position.y)] != leftSide){
        
        // set velocity to 0
        _velocity.x = 0;
        // ball can't move any further left
        _position.x += 1;
        // printf("left side hit \n");
    }
    
    if (rightSide + _mazeArray[rightSide + 1][int(_position.y)] != rightSide){
        
        _velocity.x = 0;
        _position.x -= 1;
        // printf("right side hit \n");
    }
    
    
    if (topSide + _mazeArray[int(_position.x)][topSide - 1] != topSide){
        
        _velocity.y = 0;
        _position.y += 1;
        // printf("top side hit \n");
    }
    
    if (lowerSide + _mazeArray[int(_position.x)][lowerSide + 1] != lowerSide){
        
        _velocity.y = 0;
        _position.y -= 1;
        // printf("low side hit \n");
    }
    
    _ball.setPosition(_position);
    _ball.setVelocity(_velocity);
}

/**
 *  @details - updates the game
 */
void MazeEngine::update(N5110 &lcd)
{
    // check if ball is in goal before moving to next position
    if (checkGoal()){
        
        // printf("Goal reached");
        return;
    }
    
    // changes the location of the ball according to inputs
    _ball.update(position);
    
    // reverts the changes if the proposed new position sends ball
    // into the wall
    checkWallCollision(lcd);
    
}

/**
 *  @details - Acquires maze array used for wall collision checks
 */
void MazeEngine::getMazeArray(N5110 &lcd)
{
    for (int i = 0; i < 84; i++){
        for (int j = 0; j < 48; j++){
            
            int pixel = lcd.getPixel(i, j);
            
            if (pixel == 1){
                
                _mazeArray[i][j] = 1;
            }
            else {
                
                _mazeArray[i][j] = 0;
            }
        }
        
    }
}

/**
*   @details - Draws ball and maze
*/
void MazeEngine::draw(N5110 &lcd)
{
    // mazes are drawn according to selected maze index (default = 0)
    _maze.draw(lcd);
    // array acquired for wall collisions
    getMazeArray(lcd);
    
    _ball.draw(lcd);
}

/**
 *  @details - Checks if goal has been achieved.
 */
bool MazeEngine::checkGoal()
{
    Vector2D position = _ball.getPosition();
    
    // completion when ball goes outside map for all mazes apart
    // from extreme (mazeIndex 9)
    if (_mazeIndex == 9){
        
        // check central region for goal
        for (int i = 41; i < 46; i++){
            for (int j = 22; j < 25; j++){
                
                if ((position.x == i) &&
                    (position.y == j)) {
                    
                    printf("Goal reached");
                    _goal = true;
                    
                    return _goal;
                }
            }
        }
    }
    
    else {
        
        if (position.x > 86){
            
            // printf("Goal reached");
            _goal = true;
            return _goal;
        }
    }
    
    return _goal;
}