Henry Triff / Mbed 2 deprecated ELEC2645_Project_el18ht

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Mechanics.cpp Source File

Mechanics.cpp

00001 #include "Mechanics.h"
00002 
00003 //--------------------------------
00004 //  CONSTRUCTORS AND DESTRUCTORS
00005 //--------------------------------
00006 
00007 Mechanics::Mechanics()
00008 {
00009 }
00010 
00011 Mechanics::~Mechanics()
00012 {
00013 }
00014 
00015 //---------
00016 //  SPEED
00017 //---------
00018 
00019 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)
00020 {
00021     bool offtrack = Is_Offtrack(position, offtrack_square, offtrack_triangle, map_info);
00022     bool out_of_bounds = Is_Out_Of_Bounds(position, out_of_bounds_square, out_of_bounds_triangle,  map_info);
00023 
00024     if(Device.X_held() == true && Device.A_held() == false) { //If accelerator is pressed and break is not
00025         if(speed >= 0 && speed < max_speed) { //If the speed is greater than 0 and less than max speed
00026             speed += acceleration; //Increase the speed
00027         } else if(speed < 0) { //If the speed is less than 0
00028             speed = 0; //Set speed to 0
00029         }
00030     } else if(Device.A_held() == true && Device.X_held() == false) { //If the break is pressed and accelerator is not
00031         if(speed > 0) { //If speed is greater than 0
00032             speed -= deceleration; //Decrease the speed
00033         } else if(speed <= 0) { //If speed is less than 0
00034             speed = -1; //Set speed to -1
00035         }
00036     } else if(Device.A_held() == false && Device.X_held() == false) { //If no button is pressed
00037         if(speed > 0) { //If speed is greater than 0
00038             speed -= 0.05; //Decrease speed gradually
00039         } else { //If speed is less than zero
00040             speed = 0; //Set speed to 0
00041         }
00042     }
00043     if(offtrack == true) { //If the car is offtrack
00044         if(speed > off_track_speed) { //If speed is greater than off track speed
00045             speed -= 0.10; //Speed is rapidly reduced
00046         }
00047     }
00048 
00049     speed = Get_Boost_Speed(plates, map_info.number_of_boost_plates, position, speed); //If the car is on a boost plate change the speed
00050 
00051 #ifdef DEBUG_SPEED
00052     printf("%f \n", speed);
00053 #endif
00054 
00055     return speed; //Return the speed
00056 }
00057 
00058 //-----------------------------------
00059 //  OFF TRACK / OUT OF BOUNDS CHECK
00060 //-----------------------------------
00061 
00062 //COMBINING
00063 bool Mechanics::Is_Offtrack(Point_2D position, const Square_2D offtrack_square[], const Triangle_2D offtrack_triangle[], const Map_Data map_info) //Check to see if the player is off track
00064 {
00065 #ifdef DEBUG_OFF_TRACK
00066     printf("%i\n",(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)));
00067 #endif
00068     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));//Return the result of checking squares and triangles
00069 }
00070 
00071 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) //Check to see if the player is out of bounds
00072 {
00073 #ifdef DEBUG_OUT_OF_BOUNDS
00074     printf("%i\n",(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)));
00075 #endif
00076     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)); //Return the result of checking squares and triangles
00077 }
00078 
00079 
00080 //  OFF TRACK
00081 bool Mechanics::Is_Offtrack_Square(const Square_2D offtrack[], int size, Point_2D position)
00082 {
00083     for(int i = 0; i < size; i++) { //Iterate through the offtrack array
00084         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 the position of the car is in the out_of_bounds square
00085             return true; //return that the car is off track
00086         }
00087     }
00088     return false; //return that the car is NOT off track
00089 }
00090 
00091 bool Mechanics::Is_Offtrack_Triangle(const Triangle_2D offtrack[], int size, Point_2D position)
00092 {
00093     for(int i = 0; i < size; i++) { //Iterate through the offtrack array
00094         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 the player is in the square area of the off track triangle
00095             if(offtrack[i].Type == 1) { //If the direction of the triangle is type 1 = Hypotenuse is on the top right
00096                 Point_2D Translated_position = {position.x - offtrack[i].TL.x, position.y - offtrack[i].TL.y}; //Compare the position of the car to the top left position of the triangle
00097                 float position_limit = (offtrack[i].BR.y - offtrack[i].TL.y) / (offtrack[i].BR.x - offtrack[i].TL.x) * Translated_position.x;  //Calculate the y coordinate of the hypotenuse of the triangle at the given x position
00098                 if(Translated_position.y < position_limit) { //If the y position of the car is less than the y position limit
00099                     return true; //Return that the car is off track
00100                 }
00101             } else if(offtrack[i].Type == 2) { //If the direction of the triangle is type 1 = Hypotenuse is on the bottom right
00102                 Point_2D Translated_position = {position.x - offtrack[i].TL.x, position.y - offtrack[i].BR.y}; //Compare the position of the car to the top bottom position of the triangle
00103                 float position_limit =  (offtrack[i].TL.y - offtrack[i].BR.y) / (offtrack[i].BR.x - offtrack[i].TL.x) * Translated_position.x;  //Calculate the y coordinate of the hypotenuse of the triangle at the given x position
00104                 if(Translated_position.y > position_limit) { //If the y position of the car is greater than the y position limit
00105                     return true; //Return that the car is off track
00106                 }
00107             } else if(offtrack[i].Type == 3) { //If the direction of the triangle is type 1 = Hypotenuse is on the bottom left
00108                 Point_2D Translated_position = {position.x - offtrack[i].TL.x, position.y - offtrack[i].TL.y}; //Compare the position of the car to the top bottom position of the triangle
00109                 float position_limit = (offtrack[i].BR.y - offtrack[i].TL.y) / (offtrack[i].BR.x - offtrack[i].TL.x) * Translated_position.x;  //Calculate the y coordinate of the hypotenuse of the triangle at the given x position
00110                 if(Translated_position.y > position_limit) { //If the y position of the car is greater than the y position limit
00111                     return true; //Return that the car is off track
00112                 }
00113             } else if(offtrack[i].Type == 4) { //If the direction of the triangle is type 1 = Hypotenuse is on the top left
00114                 Point_2D Translated_position = {position.x - offtrack[i].TL.x, position.y - offtrack[i].BR.y}; //Compare the position of the car to the top left position of the triangle
00115                 float position_limit =  (offtrack[i].TL.y - offtrack[i].BR.y) / (offtrack[i].BR.x - offtrack[i].TL.x) * Translated_position.x;  //Calculate the y coordinate of the hypotenuse of the triangle at the given x position
00116                 if(Translated_position.y < position_limit) { //If the y position of the car is less than the y position limit
00117                     return true; //Return that the car is off track
00118                 }
00119             }
00120         }
00121     }
00122     return false; //Return that the car is NOT off track
00123 }
00124 
00125 //  OUT OF BOUNDS
00126 bool Mechanics::Is_Out_Of_Bounds_Square(const Square_2D out_of_bounds[], int size, Point_2D position)
00127 {
00128     for(int i = 0; i < size; i++) { //Iterate through the out_of_bounds array
00129         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 the position of the car is in the out_of_bounds square
00130             return true; //return that the car is out of bounds
00131         }
00132     }
00133     return false; //return that the car is NOT out of bounds
00134 }
00135 
00136 bool Mechanics::Is_Out_Of_Bounds_Triangle(const Triangle_2D out_of_bounds[], int size, Point_2D position) //Calculate if the player is out of bounds when compared to triangular out of bounds
00137 {
00138     for(int i = 0; i < size; i++) { //Iterate through the out_of_bounds array
00139         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 the player is in the square area of the out of bounds triangle
00140             if(out_of_bounds[i].Type == 1) { //If the direction of the triangle is type 1 = Hypotenuse is on the top right
00141                 Point_2D Translated_position = {position.x - out_of_bounds[i].TL.x, position.y - out_of_bounds[i].TL.y}; //Compare the position of the car to the top left position of the triangle
00142                 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; //Calculate the y coordinate of the hypotenuse of the triangle at the given x position
00143                 if(Translated_position.y < position_limit) { //If the y position of the car is less than the y position limit
00144                     return true; //Return that the car is out of bounds
00145                 }
00146             } else if(out_of_bounds[i].Type == 2) { //If the direction of the triangle is type 2 = Hypotenuse is on the bottom right
00147                 Point_2D Translated_position = {position.x - out_of_bounds[i].TL.x, position.y - out_of_bounds[i].BR.y}; //Compare the position of the car to the bottom left position of the triangle
00148                 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; //Calculate the y coordinate of the hypotenuse of the triangle at the given x position
00149                 if(Translated_position.y > position_limit) {  //If the y position of the car is greater than the y position limit
00150                     return true; //Return that the car is out of bounds
00151                 }
00152             } else if(out_of_bounds[i].Type == 3) { //If the direction of the triangle is type 3 = Hypotenuse is on the bottom left
00153                 Point_2D Translated_position = {position.x - out_of_bounds[i].TL.x, position.y - out_of_bounds[i].TL.y}; //Compare the position of the car to the top left position of the triangle
00154                 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; //Calculate the y coordinate of the hypotenuse of the triangle at the given x position
00155                 if(Translated_position.y > position_limit) {  //If the y position of the car is greater than the y position limit
00156                     return true; //Return that the car is out of bounds
00157                 }
00158             } else if(out_of_bounds[i].Type == 4) { //If the direction of the triangle is type 1 = Hypotenuse is on the top left
00159                 Point_2D Translated_position = {position.x - out_of_bounds[i].TL.x, position.y - out_of_bounds[i].BR.y}; //Compare the position of the car to the bottom left position of the triangle
00160                 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; //Calculate the y coordinate of the hypotenuse of the triangle at the given x position
00161                 if(Translated_position.y < position_limit) {  //If the y position of the car is less than the y position limit
00162                     return true; //Return that the car is out of bounds
00163                 }
00164             }
00165         }
00166     }
00167     return false;  //Return that the car is NOT out of bounds
00168 }
00169 
00170 //---------------
00171 //  BOOST PLATE
00172 //---------------
00173 
00174 float Mechanics::Get_Boost_Speed(const Triangle_2D plates[], int number_of_plates, Point_2D position, float speed) //If the player is on a boost plate
00175 {
00176     for(int i = 0; i < number_of_plates; i++) { //Iterate through all boost plates
00177         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) { //If the player is in a boost plate
00178             speed = 8; //Increase the players speed to 8
00179         }
00180     }
00181     return speed; //Return the speed
00182 }
00183 
00184 //------------------
00185 //  GATES AND LAPS
00186 //------------------
00187 
00188 int Mechanics::Get_Gate(const Square_2D gates[], int number_of_gates, Point_2D position, int current_gate)
00189 {
00190     int next_gate;
00191 
00192     if(current_gate + 1 <= (number_of_gates - 1)) { //If the current gate is not the last in the array
00193         next_gate = current_gate + 1; //The next gate is the current gate + 1
00194     } else { //Else if it is the last gate in the array
00195         next_gate = 0; //Then the next gate is 0
00196     }
00197 
00198     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) { //Check if the players position is in the next gate
00199         return next_gate; //Return the current gate as being the next one
00200     }
00201 
00202 #ifdef DEBUG_GATE
00203     printf("%i\n", current_gate);
00204 #endif
00205 
00206     return current_gate; //Else if the player has not yet reached the next gate, then the current gate remains the same
00207 }
00208 
00209 int Mechanics::Get_Laps(int laps, const Square_2D gates[], int number_of_gates, Point_2D position, int current_gate) //Calculate the number of laps
00210 {
00211     int next_gate;
00212 
00213     if(current_gate + 1 <= (number_of_gates - 1)) { //If the current gate is not the last in the array
00214         next_gate = current_gate + 1; //The next gate is the current gate + 1
00215     } else { //Else if it is the last gate in the array
00216         next_gate = 0; //Then the next gate is 0
00217     }
00218     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) {
00219         if(next_gate == 0) { //If the car is in the area of the next gate and the next gate is 0
00220             laps++; //Increase the number of laps
00221         }
00222     }
00223     return laps; //Return the number of laps
00224 }
00225 
00226 //--------
00227 //  TIME
00228 //--------
00229 
00230 Time Mechanics::Convert_To_Time(int game_fps, int number_of_frames) //Convert The number of frames elapsed to minutes, seconds and miliseconds
00231 {
00232     int total_seconds = float(number_of_frames) / float(game_fps); //Calculate the total number of seconds elapsed
00233     int seconds = total_seconds % 60; //The remainder after 60 is the seconds
00234     float miliseconds_decimal = (float(number_of_frames) / float(game_fps)) - seconds; //Calculating the decimal number of miliseconds
00235     int miliseconds = float(miliseconds_decimal * 1000); //Multiplying by 1000 to get the number of miliseconds as an integer
00236     int minuites = (total_seconds - seconds) / 60; //The minutes is the total number of seconds subtract the seconds on the clock divided by 60
00237     return {minuites, seconds, miliseconds}; //Return the time
00238 }
00239 
00240 //-------------
00241 //  GET ANGLE
00242 //-------------
00243 
00244 int Mechanics::Get_Angle(int angle, int handling, bool gyro_enabled, FXOS8700CQ &Gyro, Gamepad &Device)
00245 {
00246 #ifdef DEBUG_ANGLE
00247     printf("%i\n", angle);
00248 #endif
00249 
00250     if(gyro_enabled == false) { //If we are using stick control
00251         int Stick_Position = Device.get_direction(); //The stick position is calculated
00252         float Stick_Magnitude = Device.get_mag(); //The magnitude of the stick position is calculated
00253         if(Stick_Magnitude > 0.95) { //Rounds up if almost at full magnitude
00254             Stick_Magnitude = 1;
00255         }
00256         if(Stick_Position == E || Stick_Position == NE || Stick_Position == SE) { //Allows the stick to be pushed in any right direction
00257             angle += handling * Stick_Magnitude; //The angle is increased by the handling of the car × stick magntude
00258         } else if(Stick_Position == W || Stick_Position == NW || Stick_Position == SW) { //Allows the stick to be pushed in any left direction
00259             angle -= handling * Stick_Magnitude; //The angle is decreased by the handling of the car × stick magntude
00260         }
00261         return angle; //Return the new angle of rotation of the track
00262     } else {
00263         Gyro_Data Gyro_Tilt = Gyro.get_values(); //Calculate the amount of tilt of the device
00264         float tilt = Gyro_Tilt.ay * 90; //Turn the tild into an angle from -90° to +90°
00265         if(tilt > 5) { //±5° deadzone
00266             if(tilt < 40) { //Max angle is 40°
00267                 angle += handling * (tilt/40); //Increase the angle
00268             } else {
00269                 angle += handling; //Increase the angle
00270             }
00271         } else if(tilt < -5) {//±5° deadzone
00272             if(tilt > -40) { //Max angle is -40°
00273                 angle -= handling * (tilt/-40); //Decrease the angle
00274             } else {
00275                 angle -= handling; //Decrease the angle
00276             }
00277         }
00278 
00279         return angle; //Return the new angle of roation of the track
00280     }
00281 }
00282 
00283 //-------------------
00284 //  GET TRANSLATION
00285 //-------------------
00286 
00287 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)
00288 //Calculates the change in the translation of the map, depending on the speed and direction of the cars movement
00289 {
00290     float temp_speed;
00291 
00292     //Converting to floats
00293     float x = in.x;
00294     float y = in.y;
00295 
00296     //printf("%f\n", temp_speed);
00297     y += speed * cos(-angle * PI / 180); //The change in the y position is then claculated
00298     x -= speed * sin(-angle * PI / 180); //The change in the x position is then claculated
00299 
00300     Point_2D next_translation = {x,y};
00301 
00302     //Checking to see if the car is out of bounds
00303     bool will_be_out_of_bounds = Is_Out_Of_Bounds(next_translation, out_of_bounds_square, out_of_bounds_triangle,  map_info);
00304     if(will_be_out_of_bounds == true) {
00305         #ifdef DEBUG_POSITION
00306             printf("%f,%f\n", x,y);
00307         #endif
00308         return {in.x,in.y};
00309 
00310     } else {
00311         #ifdef DEBUG_POSITION
00312             printf("%f,%f\n", x,y);
00313         #endif
00314         return {x,y};
00315     }
00316 
00317 
00318 #ifdef DEBUG_POSITION
00319     printf("%f,%f\n", x,y);
00320 #endif
00321 
00322     return {x,y};
00323 }
00324 
00325 //-----------------------------
00326 //  CAR MODELS AND PARAMETERS
00327 //-----------------------------
00328 
00329 float Mechanics::Get_Max_Speed(int car_model) //Returns the maximum speed of each vehicle
00330 {
00331     //For each car, Return the maximum speed when on track
00332     //This is the number of integer coordinates in any direction moved by the car per frame
00333     if(car_model == Stupid) {
00334         return 8;
00335     } else if(car_model == Racecar) {
00336         return 6;
00337     } else if(car_model == Sportscar) {
00338         return 4;
00339     } else if(car_model == Drifter) {
00340         return 4;
00341     } else if(car_model == Offroad) {
00342         return 2;
00343     } else if(car_model == Basic) {
00344         return 3;
00345     }
00346 }
00347 
00348 float Mechanics::Get_Acceleration(int car_model) //Returns the acceleration of each vehicle
00349 {
00350     //For each car, Return the acceleration when accelerating
00351     //This is the rate of change in the number of integer coordinates in any direction moved by the car per frame
00352     if(car_model == Stupid) {
00353         return 0.15;
00354     } else if(car_model == Racecar) {
00355         return 0.1;
00356     } else if(car_model == Sportscar) {
00357         return 0.08;
00358     } else if(car_model == Drifter) {
00359         return 0.05;
00360     } else if(car_model == Offroad) {
00361         return 0.02;
00362     } else if(car_model == Basic) {
00363         return 0.03;
00364     }
00365 
00366 }
00367 
00368 float Mechanics::Get_Deceleration(int car_model) //Returns the deceleration when the brakes are pressed for each vehicle
00369 {
00370     //For each car, Return the deceleration when breaking
00371     //This is the rate of change in the number of integer coordinates in any direction moved by the car per frame
00372     if(car_model == Stupid) {
00373         return 0.3;
00374     } else if(car_model == Racecar) {
00375         return 0.15;
00376     } else if(car_model == Sportscar) {
00377         return 0.1;
00378     } else if(car_model == Drifter) {
00379         return 0.03;
00380     } else if(car_model == Offroad) {
00381         return 0.03;
00382     } else if(car_model == Basic) {
00383         return 0.05;
00384     }
00385 }
00386 
00387 float Mechanics::Get_Off_Road_Speed(int car_model) //Returns the maximum speed that the vehicle can travel off road
00388 {
00389     //For each car, Return the max speed when off road
00390     //This is the number of integer coordinates in any direction moved by the car per frame
00391     if(car_model == Stupid) {
00392         return 2;
00393     } else if(car_model == Racecar) {
00394         return 0.5;
00395     } else if(car_model == Sportscar) {
00396         return 0.8;
00397     } else if(car_model == Drifter) {
00398         return 0.3;
00399     } else if(car_model == Offroad) {
00400         return 2;
00401     } else if(car_model == Basic) {
00402         return 0.8;
00403     }
00404 }
00405 
00406 int Mechanics::Get_Handling(int car_model) //Returns the value for the handling of each vehicle
00407 {
00408 
00409     //For each car, return the handling
00410     //Handling is the change is the max degrees of rotation of track per frame
00411     if(car_model == Stupid) {
00412         return 3;
00413     } else if(car_model == Racecar) {
00414         return 3;
00415     } else if(car_model == Sportscar) {
00416         return 2;
00417     } else if(car_model == Drifter) {
00418         return 2;
00419     } else if(car_model == Offroad) {
00420         return 1;
00421     } else if(car_model == Basic) {
00422         return 2;
00423     }
00424 }
00425 
00426 
00427 
00428 
00429 
00430 
00431