ELEC2645 (2018/19) / Mbed 2 deprecated el17ebs

Dependencies:   mbed FATFileSystem

Ball/Ball.cpp

Committer:
ellisbhastroud
Date:
2019-04-23
Revision:
10:9f54a6366e94
Parent:
9:bc34f2243e43
Child:
11:6d2027253aa9

File content as of revision 10:9f54a6366e94:

#include "Ball.h"

//constructor

Ball::Ball()
{

}

//deconstructor

Ball::~Ball()
{

}

//public methods

void Ball::init(Coord start_pos) //ball starts new level stationary in x and y positions given
{
    _x_pos = start_pos.x;
    _y_pos = start_pos.y;
    _x_vel = 0.0f;
    _y_vel = 0.0f;
    _total_shot_count = _total_shot_count + _shot_count; 
    _shot_count = 0;
}

void Ball::drawBall(N5110 &lcd)
{
    lcd.drawRect(_x_pos,_y_pos,2,2,FILL_BLACK); //draws ball 
}

void Ball::printShotCount(N5110 &lcd) 
{
    char buffer[14];
    sprintf(buffer,"Shot %i",_shot_count);
    lcd.printString(buffer,40,0);      
}

void Ball::drawPower(N5110 &lcd, float mag)
{     
    lcd.drawRect(0,1,36,6,FILL_TRANSPARENT);
    lcd.drawRect(0,1,36*mag,6,FILL_BLACK);
}


void Ball::drawAim(N5110 &lcd, Vector2D joy_coord, float angle)
{   
    if(angle != -1.0f) {
        lcd.drawLine(10,16,10+12*joy_coord.x,16+-12*joy_coord.y,1);
    }

}

void Ball::move_ball()
{
    _x_pos = _x_pos + _x_vel*10.0f/_frame_rate; //move ball position at rate proportional to velocity in each direction  
    _y_pos = _y_pos + _y_vel*10.0f/_frame_rate;   
    _x_vel = _x_vel*(1.0f-(0.6f/_frame_rate)); //ball slows down each loop caled by time between frames to ensure same movement at different frame rates
    _y_vel = _y_vel*(1.0f-(0.6f/_frame_rate));
    if(_x_vel != 0 && _y_vel != 0 && abs(_x_vel) < 0.2f && abs(_y_vel) < 0.2f) { //to make ball come to complete stop once velocity is nearly 0
        _x_vel = 0;
        _y_vel = 0;
    }  
}

Vector2D Ball::get_ball_pos()
{   
    Vector2D pos = {_x_pos, _y_pos};
    return pos;
}

void Ball::shoot_ball(Gamepad &pad, Vector2D _joy_coord)
{        
    if(pad.check_event(Gamepad::A_PRESSED) == true && abs(_x_vel) < TOL && abs(_y_vel) < TOL){ //if ball stationary and a pressed then shoot                                                                               
        _x_vel = 6.0f * _joy_coord.x; //scale x velocity by joystick direction and magnitude
        _y_vel = 6.0f * -_joy_coord.y; //scale y velocity by joystick direction and magnitude
        _shot_count ++; //increment shot count
    }

}

int Ball::get_shot_count()
{
    int shot_count = _shot_count;
    return shot_count;
}

int Ball::get_total_shot_count()
{
    int total_shot_count = _total_shot_count;    
    return total_shot_count; 
}

void Ball::set_total_shot_count(int total_shot_count)
{
    int _total_shot_count = total_shot_count;
}

bool Ball::check_hole(Coord hole) //returns true when ball is hit in hole and next level begins
{
    if(_x_pos > hole.x - 1 && _x_pos  < hole.x + 2 && _y_pos > hole.y - 1 && _y_pos < hole.y + 2) {
        _x_vel = 0; //stop ball moving
        _y_vel = 0;
        _x_pos = hole.x;
        _y_pos = hole.y;
        return true; //causes next level process to begin
    } 
    else {
        return false;
    }
}

void Ball::check_wall_bounce(WallMap map[], int size) //uses information from WallMap array for each level to check for bounces  
{
    for(int i = 0; i < size; i ++) {
    
        if(map[i].wall == LEFT) { //each bounce check algorithm uses wall type and start/end coordinates then bounces if the next frame ball position is past the wall
            left_bounce(map[i].start,map[i].end);
        }
        else if(map[i].wall == RIGHT) {
            right_bounce(map[i].start,map[i].end);        
        }
        else if(map[i].wall == TOP) {
            top_bounce(map[i].start,map[i].end);
        }
        else if(map[i].wall == BOTTOM) {
            bottom_bounce(map[i].start,map[i].end);
        }
        else if(map[i].wall == BOTTOMLEFT) {
            bottom_left_bounce(map[i].start,map[i].end);
        }
        else if(map[i].wall == BOTTOMRIGHT) {
            bottom_right_bounce(map[i].start,map[i].end);
        }
        else if(map[i].wall == TOPLEFT) {
            top_left_bounce(map[i].start,map[i].end);
        }
        else if(map[i].wall == TOPRIGHT) {
            top_right_bounce(map[i].start,map[i].end);
        }
    
    }
}

void Ball::left_bounce(Coord start, Coord end) //top check for left wall collision
{
    if(_x_pos + _x_vel*10.0f/_frame_rate - 1 < start.x && _x_pos + _x_vel*10.0f/_frame_rate - 1 > start.x - 5 && _y_pos >= start.y && _y_pos + 1 <= end.y && _x_vel < 0){ // left wall 
        _x_pos = start.x; 
        _x_vel = -_x_vel; 
    }     
}

void Ball::right_bounce(Coord start, Coord end)
{
    if(_x_pos + _x_vel*10.0f/_frame_rate + 1 > start.x && _x_pos + _x_vel*10.0f/_frame_rate + 1 < start.x + 5 && _y_pos >= start.y && _y_pos + 1 <= end.y && _x_vel > 0){ //right wall x + 1
        _x_pos = start.x - 1;
        _x_vel = -_x_vel;
    }
}

void Ball::top_bounce(Coord start, Coord end)
{
    if(_y_pos + _y_vel*10.0f/_frame_rate - 1 < start.y && _y_pos + _y_vel*10.0f/_frame_rate - 1 > start.y - 5 && _x_pos >= start.x && _x_pos + 1 <= end.x && _y_vel < 0){ //top wall y -1
        _y_pos = start.y;
        _y_vel = -_y_vel;
    }
}

void Ball::bottom_bounce(Coord start, Coord end)
{
    if(_y_pos + _y_vel*10.0f/_frame_rate + 2 > start.y && _y_pos + _y_vel*10.0f/_frame_rate + 2 < start.y + 5 && _x_pos >= start.x && _x_pos + 1 <= end.x && _y_vel > 0){ //bottom wall 
        _y_pos = start.y - 1;
        _y_vel = -_y_vel;
    }  
}

void Ball::bottom_left_bounce(Coord start, Coord end) 
{
    if((_y_pos + _y_vel*10.0f/_frame_rate + 1) > (_x_pos + _x_vel*10.0f/_frame_rate - 1) + (start.y-start.x) && _x_pos >= start.x && _x_pos <= end.x && _y_pos >= start.y  && _y_pos <= end.y ) { 
        swap(_x_vel, _y_vel); //reflects from wall with velocity directions swapped
    }     
}

void Ball::bottom_right_bounce(Coord start, Coord end) //start to end = left to right sides of line
{
    if((_x_pos + _x_vel*10.0f/_frame_rate + 1) > -(_y_pos + _y_vel*10.0f/_frame_rate + 1) + (start.x+start.y) && _x_pos >= start.x &&  _x_pos <= end.x &&_y_pos >= end.y && _y_pos <= start.y){ 
 
        _x_vel = -_x_vel;
        _y_vel = -_y_vel;
        swap(_x_vel, _y_vel); //reflects from wall with velocity directions swapped
    }
}

void Ball::top_left_bounce(Coord start, Coord end) 
{
    if((_x_pos + _x_vel*10.0f/_frame_rate - 1) < -(_y_pos + _y_vel*10.0f/_frame_rate + 1) + (start.x+start.y) && _x_pos >= start.x &&  _x_pos <= end.x &&_y_pos >= end.y && _y_pos <= start.y){ 
        _x_vel = -_x_vel; //as is negative wall
        _y_vel = -_y_vel;
        
        swap(_x_vel, _y_vel); //reflects from wall with velocity directions swapped
    }
}

void Ball::top_right_bounce(Coord start, Coord end)
{
    if((_y_pos + _y_vel*10.0f/_frame_rate - 1) < (_x_pos + _x_vel*10.0f/_frame_rate + 1) + (start.y-start.x) && _x_pos >= start.x && _x_pos <= end.x && _y_pos >= start.y && _y_pos <= end.y){ 

        swap(_x_vel, _y_vel); //reflects from wall with velocity directions swapped
    }  
}

void Ball::set_frame_rate(int frame_rate)
{
    _frame_rate = frame_rate;
}
//private methods