Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
Generated on Wed Jul 20 2022 17:42:24 by
1.7.2