Henry Triff / Mbed 2 deprecated ELEC2645_Project_el18ht

Dependencies:   mbed

Mechanics/Mechanics.cpp

Committer:
HenryWTriff
Date:
2020-03-05
Revision:
9:7b1093d3f03a
Parent:
8:4503c92acaf6
Child:
10:29126a41b1da

File content as of revision 9:7b1093d3f03a:

#include "Mechanics.h"

//*********
//  SPEED
//*********

float Mechanics::Get_Speed(float speed, float max_speed, float acceleration, float deceleration,  float off_track_speed, Point_2D position, const Square_2D *offtrack_square, const Triangle_2D *offtrack_triangle, const Square_2D *out_of_bounds_square, const Triangle_2D *out_of_bounds_triangle, const Triangle_2D *plates, const Map_Data map_info, Gamepad &Device)
{
    bool offtrack = Is_Offtrack(position, offtrack_square, offtrack_triangle, map_info);
    bool out_of_bounds = Is_Out_Of_Bounds(position, out_of_bounds_square, out_of_bounds_triangle,  map_info);

    if(Device.X_held() == true && Device.B_held() == false) {
        if(speed >= 0 && speed < max_speed) {
            speed += acceleration;
        } else if(speed < 0) {
            speed = 0;
        }
    } else if(Device.B_held() == true && Device.X_held() == false) {
        if(speed >= deceleration) {
            speed -= deceleration;
        } else if(speed <= 0) {
            speed = -1;
        }
    } else if(Device.B_held() == false && Device.X_held() == false) {
        if(speed > 0) {
            speed -= 0.05;
        } else {
            speed = 0;
        }
    }
    if(offtrack == true) {
        if(speed > off_track_speed) {
            speed -= 0.10;
        }
    }

    if(out_of_bounds == true) {
        speed = 0;
    }

    speed = Get_Boost_Speed(plates, map_info.number_of_boost_plates, position, speed);

    return speed;
}

//  COMBINING

bool Mechanics::Is_Offtrack(Point_2D position, const Square_2D offtrack_square[], const Triangle_2D offtrack_triangle[], const Map_Data map_info)
{
    return (Is_Offtrack_Square(offtrack_square, map_info.number_of_off_track_squares, position) || Is_Offtrack_Triangle(offtrack_triangle, map_info.number_of_off_track_triangles, position));
}

bool Mechanics::Is_Out_Of_Bounds(Point_2D position, const Square_2D out_of_bounds_square[], const Triangle_2D out_of_bounds_triangle[], const Map_Data map_info)
{
    return (Is_Out_Of_Bounds_Square(out_of_bounds_square, map_info.number_of_out_of_bounds_squares, position) || Is_Out_Of_Bounds_Triangle(out_of_bounds_triangle, map_info.number_of_out_of_bounds_triangles, position));
}

//  OFF TRACK

bool Mechanics::Is_Offtrack_Square(const Square_2D offtrack[], int size, Point_2D position)
{
    for(int i = 0; i < size; i++) {
        if(position.x > offtrack[i].TL.x && position.x < offtrack[i].BR.x && position.y < offtrack[i].TL.y && position.y > offtrack[i].BR.y ) {
            return true;
        }
    }
    return false;
}

bool Mechanics::Is_Offtrack_Triangle(const Triangle_2D offtrack[], int size, Point_2D position)
{
    for(int i = 0; i < size; i++) {
        if(position.x > offtrack[i].TL.x && position.x < offtrack[i].BR.x && position.y < offtrack[i].TL.y && position.y > offtrack[i].BR.y ) {
            if(offtrack[i].Type == 1) {
                Point_2D Translated_position = {position.x - offtrack[i].TL.x, position.y - offtrack[i].TL.y};
                float position_limit = (offtrack[i].BR.y - offtrack[i].TL.y) / (offtrack[i].BR.x - offtrack[i].TL.x) * Translated_position.x;
                if(Translated_position.y < position_limit) {
                    return true;
                }
            } else if(offtrack[i].Type == 2) {
                Point_2D Translated_position = {position.x - offtrack[i].TL.x, position.y - offtrack[i].BR.y};
                float position_limit =  (offtrack[i].TL.y - offtrack[i].BR.y) / (offtrack[i].BR.x - offtrack[i].TL.x) * Translated_position.x;
                if(Translated_position.y > position_limit) {
                    return true;
                }
            } else if(offtrack[i].Type == 3) {
                Point_2D Translated_position = {position.x - offtrack[i].TL.x, position.y - offtrack[i].TL.y};
                float position_limit = (offtrack[i].BR.y - offtrack[i].TL.y) / (offtrack[i].BR.x - offtrack[i].TL.x) * Translated_position.x;
                if(Translated_position.y > position_limit) {
                    return true;
                }
            } else if(offtrack[i].Type == 4) {
                Point_2D Translated_position = {position.x - offtrack[i].TL.x, position.y - offtrack[i].BR.y};
                float position_limit =  (offtrack[i].TL.y - offtrack[i].BR.y) / (offtrack[i].BR.x - offtrack[i].TL.x) * Translated_position.x;
                if(Translated_position.y < position_limit) {
                    return true;
                }
            }
        }
    }
    return false;
}

//  OUT OF BOUNDS

bool Mechanics::Is_Out_Of_Bounds_Square(const Square_2D out_of_bounds[], int size, Point_2D position)
{
    for(int i = 0; i < size; i++) {
        if(position.x > out_of_bounds[i].TL.x && position.x < out_of_bounds[i].BR.x && position.y < out_of_bounds[i].TL.y && position.y > out_of_bounds[i].BR.y ) {
            return true;
        }
    }
    return false;
}

bool Mechanics::Is_Out_Of_Bounds_Triangle(const Triangle_2D out_of_bounds[], int size, Point_2D position)
{
    for(int i = 0; i < size; i++) {
        if(position.x > out_of_bounds[i].TL.x && position.x < out_of_bounds[i].BR.x && position.y < out_of_bounds[i].TL.y && position.y > out_of_bounds[i].BR.y ) {
            if(out_of_bounds[i].Type == 1) {
                Point_2D Translated_position = {position.x - out_of_bounds[i].TL.x, position.y - out_of_bounds[i].TL.y};
                float position_limit = (out_of_bounds[i].BR.y - out_of_bounds[i].TL.y) / (out_of_bounds[i].BR.x - out_of_bounds[i].TL.x) * Translated_position.x;
                if(Translated_position.y < position_limit) {
                    return true;
                }
            } else if(out_of_bounds[i].Type == 2) {
                Point_2D Translated_position = {position.x - out_of_bounds[i].TL.x, position.y - out_of_bounds[i].BR.y};
                float position_limit =  (out_of_bounds[i].TL.y - out_of_bounds[i].BR.y) / (out_of_bounds[i].BR.x - out_of_bounds[i].TL.x) * Translated_position.x;
                if(Translated_position.y > position_limit) {
                    return true;
                }
            } else if(out_of_bounds[i].Type == 3) {
                Point_2D Translated_position = {position.x - out_of_bounds[i].TL.x, position.y - out_of_bounds[i].TL.y};
                float position_limit = (out_of_bounds[i].BR.y - out_of_bounds[i].TL.y) / (out_of_bounds[i].BR.x - out_of_bounds[i].TL.x) * Translated_position.x;
                if(Translated_position.y > position_limit) {
                    return true;
                }
            } else if(out_of_bounds[i].Type == 4) {
                Point_2D Translated_position = {position.x - out_of_bounds[i].TL.x, position.y - out_of_bounds[i].BR.y};
                float position_limit =  (out_of_bounds[i].TL.y - out_of_bounds[i].BR.y) / (out_of_bounds[i].BR.x - out_of_bounds[i].TL.x) * Translated_position.x;
                if(Translated_position.y < position_limit) {
                    return true;
                }
            }
        }
    }
    return false;
}

//  BOOST PLATE

float Mechanics::Get_Boost_Speed(const Triangle_2D plates[], int number_of_plates, Point_2D position, float speed)
{
    for(int i = 0; i < number_of_plates; i++) {
        if(position.x > plates[i].TL.x && position.x < plates[i].BR.x && position.y < plates[i].TL.y && position.y > plates[i].BR.y) {
            speed = 6;
        }
    }
    return speed;
}

//******************
//  GATES AND LAPS
//******************

int Mechanics::Get_Gate(const Square_2D gates[], int number_of_gates, Point_2D position, int current_gate)
{
    int next_gate;

    if(current_gate + 1 <= (number_of_gates - 1)) {
        next_gate = current_gate + 1;
    } else {
        next_gate = 0;
    }

    if(position.x >= gates[next_gate].TL.x && position.x <= gates[next_gate].BR.x && position.y <= gates[next_gate].TL.y && position.y >= gates[next_gate].BR.y) {
        return next_gate;
    }

    return current_gate;
}

int Mechanics::Get_Laps(int laps, const Square_2D gates[], int number_of_gates, Point_2D position, int current_gate)
{
    int next_gate;

    if(current_gate + 1 <= (number_of_gates - 1)) {
        next_gate = current_gate + 1;
    } else {
        next_gate = 0;
    }
    if(position.x >= gates[next_gate].TL.x && position.x <= gates[next_gate].BR.x && position.y <= gates[next_gate].TL.y && position.y >= gates[next_gate].BR.y) {
        if(next_gate == 0) {
            laps++;
        }
    }
    return laps;
}

//********
//  TIME
//********

Time Mechanics::Convert_To_Time(int game_fps, int number_of_frames)
{
    int total_seconds = float(number_of_frames) / float(game_fps);
    int seconds = total_seconds % 60;
    float miliseconds_decimal = (float(number_of_frames) / float(game_fps)) - seconds;
    int miliseconds = float(miliseconds_decimal * 1000);
    int minuites = (total_seconds - seconds) / 60;
    return {minuites, seconds, miliseconds};
}

//*************
//  GET ANGLE
//*************

int Mechanics::Get_Angle(int angle, int handling, bool gyro_enabled, FXOS8700CQ &Gyro, Gamepad &Device)
{
    if(gyro_enabled == false) {
        int Stick_Position = Device.get_direction();
        float Stick_Magnitude = Device.get_mag();
        printf("%f\n", Stick_Magnitude);
        if(Stick_Magnitude > 0.95) {
            Stick_Magnitude = 1;
        }
        if(Stick_Position == E || Stick_Position == NE || Stick_Position == SE) {
            angle += handling * Stick_Magnitude;
        } else if(Stick_Position == W || Stick_Position == NW || Stick_Position == SW) {
            angle -= handling * Stick_Magnitude;
        }
        return angle;
    } else {
        Gyro_Data Gyro_Tilt = Gyro.get_values();
        float tilt = Gyro_Tilt.ay * 90;
        if(tilt > 5) {
            if(tilt < 40) {
                angle += handling * (tilt/40);
            } else {
                angle += handling;
            }
        } else if(tilt < -5) {
            if(tilt > -40) {
                angle -= handling * (tilt/-40);
            } else {
                angle -= handling;
            }
        }
        return angle;
    }
}

//*******************
//  GET TRANSLATION
//*******************

Point_2D Mechanics::Get_Translation(Point_2D in, float angle, float speed, const Square_2D *out_of_bounds_square, const Triangle_2D *out_of_bounds_triangle, const Map_Data map_info, Gamepad &Device)
{
    float x = in.x;
    float y = in.y;
    bool out_of_bounds = Is_Out_Of_Bounds(in, out_of_bounds_square, out_of_bounds_triangle,  map_info);

    if(out_of_bounds == true) {
        float temp_speed = -4;
        y += temp_speed * cos(-angle * PI / 180);
        x -= temp_speed * sin(-angle * PI / 180);
    }
    y += speed * cos(-angle * PI / 180);
    x -= speed * sin(-angle * PI / 180);

    return {x,y};
}

//**************
//  CAR MODELS
//**************

float Mechanics::Get_Max_Speed(int car_model)
{
    enum cars {Basic, Offroad, Drifter, Sportscar, Racecar, Stupid};

    if(car_model == Stupid) {
        return 8;
    } else if(car_model == Racecar) {
        return 6;
    } else if(car_model == Sportscar) {
        return 4;
    } else if(car_model == Drifter) {
        return 4;
    } else if(car_model == Offroad) {
        return 2;
    } else if(car_model == Basic) {
        return 3;
    }
}

float Mechanics::Get_Acceleration(int car_model)
{
    enum cars {Basic, Offroad, Drifter, Sportscar, Racecar, Stupid};

    if(car_model == Stupid) {
        return 0.15;
    } else if(car_model == Racecar) {
        return 0.1;
    } else if(car_model == Sportscar) {
        return 0.08;
    } else if(car_model == Drifter) {
        return 0.05;
    } else if(car_model == Offroad) {
        return 0.02;
    } else if(car_model == Basic) {
        return 0.03;
    }

}

float Mechanics::Get_Deceleration(int car_model)
{
    enum cars {Basic, Offroad, Drifter, Sportscar, Racecar, Stupid};

    if(car_model == Stupid) {
        return 0.3;
    } else if(car_model == Racecar) {
        return 0.15;
    } else if(car_model == Sportscar) {
        return 0.1;
    } else if(car_model == Drifter) {
        return 0.03;
    } else if(car_model == Offroad) {
        return 0.03;
    } else if(car_model == Basic) {
        return 0.05;
    }
}

float Mechanics::Get_Off_Road_Speed(int car_model)
{
    enum cars {Basic, Offroad, Drifter, Sportscar, Racecar, Stupid};

    if(car_model == Stupid) {
        return 2;
    } else if(car_model == Racecar) {
        return 0.5;
    } else if(car_model == Sportscar) {
        return 0.8;
    } else if(car_model == Drifter) {
        return 0.3;
    } else if(car_model == Offroad) {
        return 2;
    } else if(car_model == Basic) {
        return 0.8;
    }
}

int Mechanics::Get_Handling(int car_model)
{
    enum cars {Basic, Offroad, Drifter, Sportscar, Racecar, Stupid};

    if(car_model == Stupid) {
        return 3;
    } else if(car_model == Racecar) {
        return 3;
    } else if(car_model == Sportscar) {
        return 2;
    } else if(car_model == Drifter) {
        return 2;
    } else if(car_model == Offroad) {
        return 1;
    } else if(car_model == Basic) {
        return 2;
    }
}