Josh Davy / Mbed 2 deprecated Flip

Dependencies:   mbed el17jd

Player/Player.cpp

Committer:
joshdavy
Date:
2019-05-06
Revision:
11:db27d3838514
Parent:
10:58cf89dd878c
Child:
14:1e6f74233e8e

File content as of revision 11:db27d3838514:

#include "Player.h"
/** Player Class

@brief Player Class handles the updating,location and collision detection of the
player as well as rendering the player on screen depending on the current
orientation.
@version 1.0

@author Joshua Davy el17jd

@date April 2019

*/

/**
* @brief Constructor (no paramateters)
*/

Player::Player()
{

}
/**
* @brief Deconstructor
*/
Player::~Player()
{

}


/**
* @brief Initialises the player
* @param pos @details The initial positon of the player
*/
void Player::init(Vector2D pos)
{
    _height = PLAYER_HEIGHT;
    _width = PLAYER_WIDTH;
    _pos = pos;         // Changes with the player moving
    _initial_pos = pos; // Constant
    _bitmap = (int *) player_bitmap_left; // Default
    _orientation = 1; // Upright
    _direction = -1;  // Left
}

/** 
* @brief Checks if the player is off the screen, if so returns player
* to initial position.
*/
void  Player::check_out_of_range()
{
    // If off the screen.
    if (_pos.x < -5  || _pos.x > 89 || _pos.y < -5 || _pos.y > 53) {
        // Return to initial positon.
        _pos = _initial_pos;
        _orientation = 1;
    }
}
/**
* @brief Returns true if the player has reached the goal.
* @returns if the goal has been reached
*/
bool Player::check_goal_reached(Vector2D goal)
{
    bool goal_reached = false;
    // X and Y distance from the player to the goal.
    int x_distance = abs(goal.x - _pos.x);
    int y_distance = abs(goal.y - _pos.y);
    // If within 2 pixels in the X direction and 6 pixels in the Y direction
    if (x_distance < 2 && y_distance < 6) {
        // Then the goal has been reached.
        goal_reached = true;
    }
    return goal_reached;
}
/** 
* @brief Returns true if the player can move vertically down
* @returns True if can move down
*/
bool Player::can_move_down(Block blocks [],int number_of_blocks)
{
    bool can_move_down = true;
    // For every block
    for (int i  = 0; i < number_of_blocks; i++) {
        // If the player is within the x range of the block
        if (_pos.x + _width > blocks[i].first.x &&
                _pos.x  < blocks[i].second.x) {
            // And the players bottom edge is equal to the blocks top edge
            if ( (_pos.y + _height) == blocks[i].first.y ) {
                // cant move down
                can_move_down = false;
            }
        }
    }
    return can_move_down;
}

/** 
* @brief Returns true if the player can move vertically up
* @returns True if can move up
*/
bool Player::can_move_up(Block blocks [],int number_of_blocks)
{
    bool can_move_up = true;
    // For every block
    for (int i  = 0; i < number_of_blocks; i++) {
        // If within the x range of the block
        if (_pos.x + _width > blocks[i].first.x &&
                _pos.x  < blocks[i].second.x) {
            // and the top edge of the player is equal to the bottom edge
            // of the block
            if ( (_pos.y) == blocks[i].second.y ) {
                // cant move up
                can_move_up = false;
            }
        }
    }
    return can_move_up;
}

/** 
* @brief Returns true if the player can move left
* @returns True if can move left
*/
bool Player::can_move_left(Block blocks [],int number_of_blocks)
{
    bool can_move_left = true;
    // For every block
    for (int i  = 0; i < number_of_blocks; i++) {
        // If within the y range of the block
        if (_pos.y  + _height > blocks[i].first.y &&
                _pos.y < blocks[i].second.y) {
            // And the left edge of the player is equal to the right edge of
            // the block
            if ( (_pos.x) == blocks[i].second.x ) {
                // Cant move left.
                can_move_left = false;
            }
        }
    }
    return can_move_left;
}
/** 
* @brief Returns true if the player can move right
* @returns True if can move right
*/
bool Player::can_move_right(Block blocks [],int number_of_blocks)
{
    bool can_move_right = true;
    // For every block
    for (int i  = 0; i < number_of_blocks; i++) {
        // If within the y range of the block
        if (_pos.y + _height > blocks[i].first.y &&
                _pos.y  < blocks[i].second.y) {
            // And the right edge of the player is equal to the left edge of
            // the block
            if ( (_pos.x + _width) == blocks[i].first.x ) {
                // cant move right
                can_move_right = false;
            }
        }
    }
    return can_move_right;
}

/**
* @brief Updates the sprite depending on the current orientation/direction
* @param int orientation @details Current player orientation.
* @param int direction @details Current player direction.
*/
void Player::update_sprite(int orientation, int direction)
{
    // If poiting left and  upright
    if (direction == -1 && orientation == 1) {
        _bitmap = (int *) player_bitmap_left;
    }
    // If poiting right and upright
    if (direction == 1 && orientation == 1) {
        _bitmap = (int *) player_bitmap_right;
    }
    // If poiting left and upside down
    if (direction == -1 && orientation == -1) {
        _bitmap = (int *) player_bitmap_left_flipped;
    }
    // If poiting right and upside down
    if (direction == 1 && orientation == -1) {
        _bitmap = (int *) player_bitmap_right_flipped;
    }

}

/**
* @brief Processes the gamepad buttons and updates the player accordingly
* @param Gamepad pad @details The gamepad object
* @param Block blocks [] @details The array of blocks
* @param int number_of_blocks @details The number of blocks
*/
void Player::process_inputs(Gamepad &pad,Block blocks [], int number_of_blocks)
{
    // If A pressed and touching a block vertically
    if (pad.check_event(Gamepad::A_PRESSED) &&
            (!can_move_down(blocks,number_of_blocks) ||
             !can_move_up(blocks,number_of_blocks))
       ) {
        // then flip the orientation
        if (_orientation == 1) {
            _orientation = -1;
        } else {
            _orientation = 1;
        }
    }
    // If  joystick is held left and not touching a block on the left
    if (pad.get_coord().x < -0.7f && can_move_left(blocks,number_of_blocks)) {
        // then move left and set the direction facing to -1 (left)
        _pos.x -= SPEED;
        _direction = -1;
    }
    // If joystick is held right and not touching a block on the right
    if (pad.get_coord().x > 0.7f && can_move_right(blocks,number_of_blocks)) {
        // then move right and set the direction facing to 1 (right)
        _pos.x += SPEED;
        _direction = 1;
    }
}

/**
* @brief Updates the player position due to gravity
* @param Block blocks [] @details The array of blocks
* @param int number_of_blocks @details The number of blocks
*/
void Player::gravity(Block blocks [], int number_of_blocks)
{
    // If upright and can move down gravity increases the position
    if (_orientation == 1 && can_move_down( blocks,
                                            number_of_blocks)) {
        _pos.y += GRAVITY;
    }
    // If upside down and can move up gravity decreases the position
    if (_orientation == -1 && can_move_up(blocks,
                                          number_of_blocks)) {
        _pos.y -= GRAVITY;
    }

}
/**
* @brief Updates the player. Should be called every frame.
* @param Block blocks [] @details The array of blocks
* @param int number_of_blocks @details The number of blocks
*/
void Player::update(Gamepad &pad, Block blocks [],int number_of_blocks)
{
    process_inputs(pad,blocks,number_of_blocks);
    gravity(blocks,number_of_blocks);
    check_out_of_range();
    update_sprite(_orientation,_direction);
}