Game

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Graphics.cpp Source File

Graphics.cpp

00001 #include "Graphics.h"
00002 
00003 Graphics::Graphics()
00004 {
00005 }
00006 
00007 Graphics::~Graphics()
00008 {
00009 }
00010 
00011 //-----------
00012 //  SPRITES
00013 //-----------
00014 
00015 #include "Sprites.h"
00016 
00017 //--------------------------
00018 //  MAIN GRAPHICS FUNCTION
00019 //--------------------------
00020 // This is the main function for the graphics.
00021 // It is a LARGE function but it reduces the clutter in main.cpp
00022 // This is run once every frame.
00023 
00024 void Graphics::Draw_Map(Point_2D translation, int angle, float squish, float horizon_factor, Line_2D *Track_Lines, Line_2D *Track_Dotted_Lines, Line_2D *Track_Walls, Sprite_2D *Track_Sprites, Triangle_2D *Track_Boost_Plates, Map_Data map_info, int car_type, Point_2D ghost_position, N5110 &LCD)
00025 {
00026     //Variable declaration
00027     enum cars {Basic, Offroad, Drifter, Sportscar, Racecar, Stupid};
00028     Line_2D Track_Lines_Transformed[map_info.number_of_track_lines];
00029     Line_2D Track_Dotted_Lines_Transformed[map_info.number_of_dotted_lines];
00030     Point_2D Transformed_Sprites[map_info.number_of_sprites];
00031     Line_2D Transformed_Walls[map_info.number_of_walls];
00032     Point_2D Transformed_Ghost;
00033 
00034     //Transforms the points of the track lines
00035     for(int i = 0; i < map_info.number_of_track_lines; i++) { //Iterates through the given track array
00036         Track_Lines_Transformed[i] = Track_Lines[i];
00037         //Translation
00038         Track_Lines_Transformed[i].from = Translate_Point(Track_Lines_Transformed[i].from, Round(translation.x), Round(translation.y));
00039         Track_Lines_Transformed[i].to = Translate_Point(Track_Lines_Transformed[i].to, Round(translation.x), Round(translation.y));
00040         //Rotation
00041         Track_Lines_Transformed[i].from = Rotate_Point(Track_Lines_Transformed[i].from, angle);
00042         Track_Lines_Transformed[i].to = Rotate_Point(Track_Lines_Transformed[i].to, angle);
00043         //Horizon
00044         Track_Lines_Transformed[i].from = Horizon_Point(Track_Lines_Transformed[i].from, horizon_factor);
00045         Track_Lines_Transformed[i].to = Horizon_Point(Track_Lines_Transformed[i].to, horizon_factor);
00046         //Squish
00047         Track_Lines_Transformed[i].from = Squish_Point(Track_Lines_Transformed[i].from, squish);
00048         Track_Lines_Transformed[i].to = Squish_Point(Track_Lines_Transformed[i].to, squish);
00049     }
00050 
00051     //Transforms the points of the dotted lines on the track
00052     for(int i = 0; i < map_info.number_of_dotted_lines; i++) { //Iterates through the given dotted lines array
00053         Track_Dotted_Lines_Transformed[i] = Track_Dotted_Lines[i];
00054         //Translation
00055         Track_Dotted_Lines_Transformed[i].from = Translate_Point(Track_Dotted_Lines_Transformed[i].from, Round(translation.x), Round(translation.y));
00056         Track_Dotted_Lines_Transformed[i].to = Translate_Point(Track_Dotted_Lines_Transformed[i].to, Round(translation.x), Round(translation.y));
00057         //Rotation
00058         Track_Dotted_Lines_Transformed[i].from = Rotate_Point(Track_Dotted_Lines_Transformed[i].from, angle);
00059         Track_Dotted_Lines_Transformed[i].to = Rotate_Point(Track_Dotted_Lines_Transformed[i].to, angle);
00060         //Horizon
00061         Track_Dotted_Lines_Transformed[i].from = Horizon_Point(Track_Dotted_Lines_Transformed[i].from, horizon_factor);
00062         Track_Dotted_Lines_Transformed[i].to = Horizon_Point(Track_Dotted_Lines_Transformed[i].to, horizon_factor);
00063         //Squish
00064         Track_Dotted_Lines_Transformed[i].from = Squish_Point(Track_Dotted_Lines_Transformed[i].from, squish);
00065         Track_Dotted_Lines_Transformed[i].to = Squish_Point(Track_Dotted_Lines_Transformed[i].to, squish);
00066     }
00067 
00068     //Transforms the points of the start flags
00069     for(int i = 0; i < map_info.number_of_sprites; i++) { //Iterates through the given flags array
00070         Transformed_Sprites[i].x = Track_Sprites[i].x;
00071         Transformed_Sprites[i].y = Track_Sprites[i].y;
00072         //Translation
00073         Transformed_Sprites[i] = Translate_Point(Transformed_Sprites[i], Round(translation.x), Round(translation.y));
00074         //Rotation
00075         Transformed_Sprites[i] = Rotate_Point(Transformed_Sprites[i], angle);
00076         //Horizon
00077         Transformed_Sprites[i] = Horizon_Point(Transformed_Sprites[i], horizon_factor);
00078         //Squish
00079         Transformed_Sprites[i] = Squish_Point(Transformed_Sprites[i], squish);
00080     }
00081 
00082     //Transforms the points of the  walls
00083     for(int i = 0; i < map_info.number_of_walls; i++) { //Iterates throught the given walls array
00084         Transformed_Walls[i] = Track_Walls[i];
00085         //Translation
00086         Transformed_Walls[i].from = Translate_Point(Transformed_Walls[i].from, Round(translation.x), Round(translation.y));
00087         Transformed_Walls[i].to = Translate_Point(Transformed_Walls[i].to, Round(translation.x), Round(translation.y));
00088         //Rotation
00089         Transformed_Walls[i].from = Rotate_Point(Transformed_Walls[i].from, angle);
00090         Transformed_Walls[i].to = Rotate_Point(Transformed_Walls[i].to, angle);
00091         //Horizon
00092         Transformed_Walls[i].from = Horizon_Point(Transformed_Walls[i].from, horizon_factor);
00093         Transformed_Walls[i].to = Horizon_Point(Transformed_Walls[i].to, horizon_factor);
00094         //Squish
00095         Transformed_Walls[i].from = Squish_Point(Transformed_Walls[i].from, squish);
00096         Transformed_Walls[i].to = Squish_Point(Transformed_Walls[i].to, squish);
00097     }
00098 
00099     //Transforms the points of the ghost position
00100     Transformed_Ghost = ghost_position;
00101     //Translation
00102     Transformed_Ghost = Translate_Point(Transformed_Ghost, Round(translation.x), Round(translation.y));
00103     //Rotation
00104     Transformed_Ghost = Rotate_Point(Transformed_Ghost, angle);
00105     //Horizon
00106     Transformed_Ghost = Horizon_Point(Transformed_Ghost, horizon_factor);
00107     //Squish
00108     Transformed_Ghost = Squish_Point(Transformed_Ghost, squish);
00109     Transformed_Ghost.x = Transformed_Ghost.x + 4;
00110 
00111     //Draws the track lines
00112     for(int i = 0; i < map_info.number_of_track_lines; i++) { //Iterates through each line
00113         Graphics_Draw_Line(Track_Lines_Transformed[i].from, Track_Lines_Transformed[i].to, true, LCD);
00114     }
00115 
00116     //Draws the dotted lines
00117     for(int i = 0; i < map_info.number_of_dotted_lines; i++) { //Iterates through each line
00118         Graphics_Draw_Line(Track_Dotted_Lines_Transformed[i].from, Track_Dotted_Lines_Transformed[i].to,false, LCD);
00119     }
00120 
00121     //Draws the boost plates
00122     for(int i = 0; i < map_info.number_of_boost_plates; i++) { //Iterates through each plate
00123         Graphics_Draw_Boost_Plate(Track_Boost_Plates[i], translation, angle, squish, LCD);
00124     }
00125 
00126     //Draws the ghost
00127     Graphics_Draw_Sprite(Transformed_Ghost, 8, 8, (int *)ghost, LCD);
00128 
00129     //Draws the walls
00130     for(int i = 0; i < map_info.number_of_walls; i++) {
00131         Graphics_Draw_Wall(Transformed_Walls[i].from, Transformed_Walls[i].to,4, LCD);
00132     }
00133     
00134     //Draws the flags
00135     for(int i = 0; i < map_info.number_of_sprites; i++) { //Iterates through each flag
00136         if(Track_Sprites[i].type == Flag) {
00137             Graphics_Draw_Sprite(Transformed_Sprites[i], 8, 8, (int *)flag, LCD);
00138         } else if(Track_Sprites[i].type == Helicopter) {
00139             Graphics_Draw_Sprite(Transformed_Sprites[i], 48, 24, (int *)helicopter, LCD);
00140         } else if(Track_Sprites[i].type == People_Cheering) {
00141             Graphics_Draw_Sprite(Transformed_Sprites[i], 8, 12, (int *)person_cheering, LCD);
00142         } else if(Track_Sprites[i].type == People_Standing_1) {
00143             Graphics_Draw_Sprite(Transformed_Sprites[i], 6, 12, (int *)person_standing_1, LCD);
00144         } else if(Track_Sprites[i].type == People_Standing_2) {
00145             Graphics_Draw_Sprite(Transformed_Sprites[i], 6, 12, (int *)person_standing_2, LCD);
00146         }
00147     }
00148 
00149     //Draws the players car
00150     Point_2D car_position = {0,0};
00151     if(car_type == Stupid) {
00152         Graphics_Draw_Sprite(car_position,8,8,(int *)stupid_car, LCD);
00153     } else if(car_type == Racecar) {
00154         Graphics_Draw_Sprite(car_position,8,8,(int *)race_car, LCD);
00155     } else if(car_type == Sportscar) {
00156         Graphics_Draw_Sprite(car_position,8,8,(int *)sports_car, LCD);
00157     } else if(car_type == Drifter) {
00158         Graphics_Draw_Sprite(car_position,8,8,(int *)drifter_car, LCD);
00159     } else if(car_type == Offroad) {
00160         Graphics_Draw_Sprite(car_position,8,8,(int *)offroad_car, LCD);
00161     } else {
00162         Graphics_Draw_Sprite(car_position,8,8,(int *)basic_car, LCD);
00163     }
00164 }
00165 
00166 //--------------
00167 //  START LOGO
00168 //--------------
00169 
00170 void Graphics::Draw_Logo(N5110 &LCD) //Draw the game logo
00171 {
00172     LCD.clear();
00173     LCD.drawSprite(0,0,48,84,(int *)logo);
00174     LCD.refresh();
00175     wait(1);
00176 }
00177 
00178 //-------------------
00179 //  SCREEN SETTINGS
00180 //-------------------
00181 
00182 void Graphics::Change_Contrast(N5110 &LCD, Gamepad &Device) //Sets the contrast with a greater level of precision
00183 {
00184     LCD.setContrast((0.35 + 0.2 * Device.read_pot1()));
00185 }
00186 
00187 //---------------------------
00188 //  RACE START / END SCREEN
00189 //---------------------------
00190 
00191 //START
00192 void Graphics::Start_Sequence(int state, N5110 &LCD) //Display the countdown numbers before the race starts
00193 {
00194     Point_2D count_down_position = {0,8};
00195     if(state == 3) {
00196         Graphics_Draw_Sprite(count_down_position, 17, 17, (int *) count_down_3, LCD);
00197     } else if(state == 2) {
00198         Graphics_Draw_Sprite(count_down_position, 17, 17, (int *) count_down_2, LCD);
00199     } else if(state == 1) {
00200         Graphics_Draw_Sprite(count_down_position, 17, 17, (int *) count_down_1, LCD);
00201     } else if(state == 0) {
00202         Graphics_Draw_Sprite(count_down_position, 18, 18, (int *) count_down_0, LCD);
00203     }
00204 
00205 }
00206 
00207 //FINISH
00208 void Graphics::Finish(N5110 &LCD) //When the race is over draw the cup symbol
00209 {
00210     Point_2D finish_position = {0,8};
00211     Graphics_Draw_Sprite(finish_position, 16, 16, (int *) cup, LCD);
00212 }
00213 
00214 //--------------------
00215 //  DRAW LAP COUNTER
00216 //--------------------
00217 
00218 void Graphics::Draw_Laps(int laps, N5110 &LCD) //Prints the lab counter in the bottom left corner
00219 {
00220     if(laps == 1) {
00221         LCD.printString("1",0,5);
00222     } else if (laps == 2) {
00223         LCD.printString("2",0,5);
00224     } else if (laps == 3) {
00225         LCD.printString("3",0,5);
00226     } else if (laps == 4) {
00227         LCD.printString("4",0,5);
00228     } else if (laps == 5) {
00229         LCD.printString("5",0,5);
00230     }
00231 }
00232 
00233 //-------------------
00234 //  DRAW RACE CLOCK
00235 //-------------------
00236 
00237 void Graphics::Draw_Time(bool finished, Time time, N5110 &LCD) //Displays the lap time
00238 {
00239     if(finished == false) { //If the race is over, Print the time in the middle of the screen
00240         char min[1];
00241         sprintf(min, "%i", time.mins); //Converts min integer to char
00242         LCD.printString(min,47,5); //Prints the min char on the screen
00243 
00244         LCD.printString(":",52,5);
00245 
00246         if(time.secs < 10) { //If the number of seconds is less than 10
00247             LCD.printString("0",57,5); //Draw a 0
00248             char sec[1];
00249             sprintf(sec, "%i", time.secs); //Converts sec integer to char
00250             LCD.printString(sec,63,5); //Prints the sec char on the screen
00251         } else {
00252             char sec[2];
00253             sprintf(sec, "%i", time.secs); //Converts sec integer to char
00254             LCD.printString(sec,57,5); //Prints the sec char on the screen
00255         }
00256 
00257         LCD.printString(".",68,5);
00258 
00259         char mili[2];
00260         sprintf(mili, "%i", time.milis); //Convers mili integer to char
00261         LCD.printString(mili,73,5); //Prints the mili char on the screen
00262     } else { //If the race is still ongoing
00263         char min[1];
00264         sprintf(min, "%i", time.mins); //Convers min integer to char
00265         LCD.printString(min,23,0); //Prints the min char on the screen
00266 
00267         LCD.printString(":",28,0);
00268 
00269         if(time.secs < 10) { //If the number of seconds is less than 10
00270             LCD.printString("0",33,0); //Draw a 0
00271             char sec[1];
00272             sprintf(sec, "%i", time.secs); //Convers sec integer to char
00273             LCD.printString(sec,39,0); //Prints the sec char on the screen
00274         } else {
00275             char sec[2];
00276             sprintf(sec, "%i", time.secs); //Convers sec integer to char
00277             LCD.printString(sec,33,0); //Prints the sec char on the screen
00278         }
00279 
00280         LCD.printString(".",44,0);
00281 
00282         char mili[2];
00283         sprintf(mili, "%i", time.milis); //Convers mili integer to char
00284         LCD.printString(mili,49,0); //Prints the mili char on the screen
00285     }
00286 }
00287 
00288 //-------------------
00289 //  TRANSFORMATIONS
00290 //-------------------
00291 
00292 //ROTATE
00293 Point_2D Graphics::Rotate_Point(Point_2D point, float angle) //Rotates all points around the origin
00294 {
00295     angle = (angle * PI)/180; //The angle given in degrees is changed into radian form
00296     float x_rotated = point.x * cos(angle) - point.y * sin(angle); //X-points are rotated about the origin
00297     float y_rotated = point.y * cos(angle) + point.x * sin(angle); //Y-points are rotated about the origin
00298     return {x_rotated, y_rotated};
00299 }
00300 //TRANSLATE
00301 Point_2D Graphics::Translate_Point(Point_2D point, int translate_x, int translate_y) //Translates all point by a given translationg
00302 {
00303     float x_translated = point.x - translate_x; //Translates the x-points
00304     float y_translated = point.y - translate_y; //Translates the y-points
00305     return {x_translated, y_translated};
00306 }
00307 
00308 //HORIZONED
00309 Point_2D Graphics::Horizon_Point(Point_2D point, float horizon_factor) //Makes all points look like they are following the horizon
00310 {
00311     float x_horizoned;
00312     if(point.x > 0) {
00313         x_horizoned = point.x - point.y * horizon_factor;
00314     } else {
00315         x_horizoned = point.x + point.y * horizon_factor;
00316     }
00317     return {x_horizoned, point.y};
00318 }
00319 
00320 //SQUISH
00321 //To get the 3D perspective, the y-coordinate is reduced by a factor
00322 Point_2D Graphics::Squish_Point(Point_2D point, float squish) //Squishes all y-coordinates by a factor
00323 {
00324     float x_squish = point.x; //The x-coordinate remains the same
00325     float y_squish = point.y * squish; //The y-coordinate is reduced
00326     return {x_squish, y_squish};
00327 }
00328 
00329 //--------
00330 //  MATH
00331 //--------
00332 
00333 //ROUNDING FLOATING POINT NUMBERS
00334 int Graphics::Round(float number) //Simple function that rounds floating point numbers
00335 {
00336     int number_int = (number * 10); //The number is multiplied by 10
00337     int remainder = number_int % 10; //The remainder when dividing by 10 is calculated
00338     if(remainder < 5) { //If the number is less than 5
00339         return ((number_int - remainder) / 10); //Round down
00340     } else {
00341         return ((number_int + (10 - remainder)) / 10); //Round up
00342     }
00343 }
00344 
00345 //CALCULATING THE GRADIENT OF A LINE
00346 float Graphics::Gradient(Point_2D from, Point_2D to) //Calculates the gradient of the line between two points
00347 {
00348     float change_in_y = to.y - from.y; //Calculates the change in the y-values of the two points
00349     float change_in_x = to.x - from.x; //Calculates the change in the x-values of the two points
00350     float gradient = change_in_y / change_in_x; //Calculates the gradient by doing dy/dx
00351     if(gradient < 0.001 && gradient > -0.001) { //If the gradient is aproximately 0
00352         return 0; //Return zero
00353     } else {
00354         return gradient; //Else return the gradient
00355     }
00356 }
00357 
00358 //CHECKING IF A GRADIENT IS VERY LARGE
00359 bool Graphics::Gradient_Check_Infinate(Point_2D from, Point_2D to) //Checks to see if the gradient is vertical
00360 {
00361     float change_in_x = to.x - from.x; //Calculates the change in the x-value
00362     if(change_in_x < 0.001 && change_in_x > -0.001) { //If the change in x value is very small
00363         return true;
00364     } else {
00365         return false;
00366     }
00367 }
00368 
00369 //-------------
00370 //  DRAW LINE
00371 //-------------
00372 
00373 void Graphics::Graphics_Draw_Line(Point_2D from, Point_2D to, bool solid, N5110 &LCD) //Draw a line between two points on only the portion of the screen
00374 {
00375 
00376     if( Gradient_Check_Infinate(from, to)  == false ) { //Checking to see if the line is vertical
00377         //Initialising variables
00378         Point_2D plot_x_from = {0,0};
00379         Point_2D plot_x_to = {0,0};
00380         Point_2D plot_y_from = {0,0};
00381         Point_2D plot_y_to = {0,0};
00382 
00383         float gradient = Gradient(from, to); // Calculating the gradient
00384         float y_intercept = (from.y - gradient * from.x); // Calulating the y intercept y - mx = c
00385         float x_intercept = (from.x - from.y / gradient); // Calculating the x intercept x - y/m = d
00386 
00387         if(gradient <= 1 && gradient >= -1) {
00388             //Reordering 'from' and 'to' so that the for loops below can use ++
00389             if(to.x < from.x) {
00390                 plot_x_from = to;
00391                 plot_x_to = from;
00392             } else {
00393                 plot_x_from = from;
00394                 plot_x_to = to;
00395             }
00396             if(solid == true) { //If the line is solid or dotted
00397                 for(int x = Round(plot_x_from.x); x <= Round(plot_x_to.x); x++) { //Iterating through the x points
00398                     int y = -(Round((gradient * x) + y_intercept)); //Calculating the value of y for each x point
00399                     Point_2D plot_x = {x+42, y+36}; //Assigning them to a Plot_2D variable and transforming so the centre of the screen is 0,0
00400                     if(plot_x.x <= 84 && plot_x.x >= 0 && plot_x.y <=48 && plot_x.y >= 0) { //Checking to see if the point is on the screen
00401                         LCD.setPixel(plot_x.x, plot_x.y, true); //Plotting the points
00402                     }
00403                 }
00404             } else {
00405                 for(int x = Round(plot_x_from.x); x <= Round(plot_x_to.x); x+=2) { //Iterating through the x points
00406                     int y = -(Round((gradient * x) + y_intercept)); //Calculating the value of y for each x point
00407                     Point_2D plot_x = {x+42, y+36}; //Assigning them to a Plot_2D variable and transforming so the centre of the screen is 0,0
00408                     if(plot_x.x <= 84 && plot_x.x >= 0 && plot_x.y <=48 && plot_x.y >= 0) { //Checking to see if the point is on the screen
00409                         LCD.setPixel(plot_x.x, plot_x.y, true); //Plotting the points
00410                     }
00411                 }
00412             }
00413         } else {
00414             //Reordering 'from' and 'to' so that the for loops below can use ++
00415             if(to.y < from.y) {
00416                 plot_y_from = to;
00417                 plot_y_to = from;
00418             } else {
00419                 plot_y_from = from;
00420                 plot_y_to = to;
00421             }
00422             if(solid == true) { //If the line is solid or dotted
00423                 for(int y = Round(plot_y_from.y); y <= Round(plot_y_to.y); y++) { //Iterating through the Y points
00424                     int x = Round((y / gradient) + x_intercept); //Calculating the value of x for every y point
00425                     Point_2D plot_y = {x+42, (-y)+36}; //Assigning them to a Plot_2D variable and transforming so the centre of the screen is 0,0
00426                     if(plot_y.x <= 84 && plot_y.x >= 0 && plot_y.y <=48 && plot_y.y >= 0) { //Checking to see if the point is on the screen
00427                         LCD.setPixel(plot_y.x, plot_y.y, true); //Plotting the points
00428                     }
00429                 }
00430             } else {
00431                 for(int y = Round(plot_y_from.y); y <= Round(plot_y_to.y); y+=2) { //Iterating through the Y points
00432                     int x = Round((y / gradient) + x_intercept); //Calculating the value of x for every y point
00433                     Point_2D plot_y = {x+42, (-y)+36}; //Assigning them to a Plot_2D variable and transforming so the centre of the screen is 0,0
00434                     if(plot_y.x <= 84 && plot_y.x >= 0 && plot_y.y <=48 && plot_y.y >= 0) { //Checking to see if the point is on the screen
00435                         LCD.setPixel(plot_y.x, plot_y.y, true); //Plotting the points
00436                     }
00437                 }
00438             }
00439         }
00440 
00441     } else {
00442         Point_2D plot_y_from = {0,0};
00443         Point_2D plot_y_to = {0,0};
00444         //Reordering from and to so that the for loops below can use ++
00445         if(to.y < from.y) {
00446             plot_y_from = to;
00447             plot_y_to = from;
00448         } else {
00449             plot_y_from = from;
00450             plot_y_to = to;
00451         }
00452         float x_intercept = from.x; //Calculating the x_intercept
00453         if(solid == true) { //If the line is solid or dotted
00454             for(int y = plot_y_from.y; y <= plot_y_to.y; y++) {
00455                 Point_2D plot_y = {x_intercept+42, (-y)+36}; //Assigning them to a Plot_2D variable and transforming so the centre of the screen is 0,0
00456                 LCD.setPixel(plot_y.x, plot_y.y, true); //Plotting the points
00457             }
00458         } else {
00459             for(int y = plot_y_from.y; y <= plot_y_to.y; y+=2) {
00460                 Point_2D plot_y = {x_intercept+42, (-y)+36}; //Assigning them to a Plot_2D variable and transforming so the centre of the screen is 0,0
00461                 LCD.setPixel(plot_y.x, plot_y.y, true); //Plotting the points
00462             }
00463         }
00464     }
00465 }
00466 
00467 //---------------
00468 //  DRAW SPRITE
00469 //---------------
00470 
00471 void Graphics::Graphics_Draw_Sprite(Point_2D point, int x_size, int y_size, int *sprite, N5110 &LCD) //Similar to N5110 drawSprite function but mine uses the origin as poin 0,0 and allows for transparent pixels
00472 {
00473     Point_2D zeroed_point = {Round(point.x) + 42 - (x_size / 2), Round(-point.y) + 36 - y_size};
00474     for (int i = 0; i < y_size; i++) {
00475         for (int j = 0 ; j < x_size ; j++) {
00476             int pixel = *((sprite+i*x_size)+j);
00477             if(pixel == 1 || pixel == 0) {
00478                 int x = zeroed_point.x+j;
00479                 int y = zeroed_point.y+i;
00480                 if(x <= 84 && x >= 0 && y <= 48 && y >= 0) { //If the point is on the screen
00481                     LCD.setPixel(x,y, pixel);
00482                 }
00483             }
00484         }
00485     }
00486 }
00487 
00488 //-------------
00489 //  DRAW WALL
00490 //-------------
00491 
00492 void Graphics::Graphics_Draw_Wall(Point_2D from, Point_2D to, int height, N5110 &LCD) //Draw a line between two points on only the portion of the screen
00493 {
00494     if(Gradient_Check_Infinate(from, to) == 0) { //Checking to see if the line is vertical
00495         //Declaring points
00496         Point_2D plot_x_from = {0,0};
00497         Point_2D plot_x_to = {0,0};
00498         Point_2D plot_y_from = {0,0};
00499         Point_2D plot_y_to = {0,0};
00500 
00501         float gradient = Gradient(from, to); // Calculating the gradient
00502         float y_intercept = (from.y - gradient * from.x); // Calulating the y intercept y - mx = c
00503         float x_intercept = (from.x - from.y / gradient); // Calculating the x intercept x - y/m = d
00504 
00505         if(gradient <= 1 && gradient >= -1) {
00506             //Reordering 'from' and 'to' so that the for loops below can use ++
00507             if(to.x < from.x) {
00508                 plot_x_from = to;
00509                 plot_x_to = from;
00510             } else {
00511                 plot_x_from = from;
00512                 plot_x_to = to;
00513             }
00514             for(int x = Round(plot_x_from.x); x <= Round(plot_x_to.x); x++) { //Iterating through the x points
00515                 int y = -(Round((gradient * x) + y_intercept)); //Calculating the value of y for each x point
00516                 Point_2D plot_x = {x+42, y+36}; //Assigning them to a Plot_2D variable and transforming so the centre of the screen is 0,0
00517                 if(plot_x.x <= 84 && plot_x.x >= 0 && plot_x.y <=48 && plot_x.y >= 0) { //Checking to see if the point is on the screen
00518                     for(int y_add = 0; y_add < height; y_add++) { //To differentiate it from a line, 'heigh' number of pixels above the line are also drawn.  This gives the impression of height
00519                         LCD.setPixel(plot_x.x, plot_x.y - y_add, true); //Plotting the point
00520                     }
00521                 }
00522             }
00523         } else {
00524             //Reordering 'from' and 'to' so that the for loops can use ++
00525             if(to.y < from.y) {
00526                 plot_y_from = to;
00527                 plot_y_to = from;
00528             } else {
00529                 plot_y_from = from;
00530                 plot_y_to = to;
00531             }
00532             for(int y = Round(plot_y_from.y); y <= Round(plot_y_to.y); y++) { //Iterating through the Y points
00533                 int x = Round((y / gradient) + x_intercept); //Calculating the value of x for every y point
00534                 Point_2D plot_y = {x+42, (-y)+36}; //Assigning them to a Plot_2D variable and transforming so the centre of the screen is 0,0
00535                 if(plot_y.x <= 84 && plot_y.x >= 0 && plot_y.y <=48 && plot_y.y >= 0) { //Checking to see if the point is on the screen
00536                     for(int y_add = 0; y_add < height; y_add++) { //To differentiate it from a line, 'heigh' number of pixels above the line are also drawn. This gives the impression of height
00537                         LCD.setPixel(plot_y.x, plot_y.y - y_add, true); //Plotting the point
00538                     }
00539                 }
00540             }
00541         }
00542 
00543     } else {
00544         //Declaring and initialising points
00545         Point_2D plot_y_from = {0,0};
00546         Point_2D plot_y_to = {0,0};
00547         //Reordering from and to so that the for loops below can use ++
00548         if(to.y < from.y) {
00549             plot_y_from = to;
00550             plot_y_to = from;
00551         } else {
00552             plot_y_from = from;
00553             plot_y_to = to;
00554         }
00555         float x_intercept = from.x; //Calculating the x_intercept
00556         for(int y = plot_y_from.y; y <= plot_y_to.y; y++) {
00557             Point_2D plot_y = {x_intercept+42, (-y)+36}; //Assigning them to a Plot_2D variable and transforming so the centre of the screen is 0,0
00558             for(int y_add = 0; y_add < height; y_add++) { //To differentiate it from a line, 'heigh' number of pixels above the line are also drawn.  This gives the impression of height
00559                 LCD.setPixel(plot_y.x, plot_y.y - y_add, true); //Plotting the point
00560             }
00561         }
00562 
00563     }
00564 }
00565 
00566 //--------------------
00567 //  DRAW BOOST PLATE
00568 //--------------------
00569 
00570 void Graphics::Graphics_Draw_Boost_Plate(Triangle_2D boost_plate, Point_2D translation, int angle, float squish, N5110 &LCD) //Draws a boost plate on the track
00571 {
00572     //Using the given coordinates, calculates the points of all corners of the boost plate
00573     Point_2D boost_plate_TL = boost_plate.TL;
00574     Point_2D boost_plate_TR = {boost_plate.BR.x, boost_plate.TL.y};
00575     Point_2D boost_plate_BL = {boost_plate.TL.x, boost_plate.BR.y};
00576     Point_2D boost_plate_BR = boost_plate.BR;
00577     Point_2D boost_plate_mid; //The coordinate of the point of the arrow of the boost plate
00578     //The type defines the direction the plate is facing, e.g. Noth, South, East, West
00579     if(boost_plate.Type == 1) {
00580         //Calculates the coordinate of the point of the arrow drawn on the boost plate
00581         boost_plate_mid.x = boost_plate_BR.x;
00582         boost_plate_mid.y = (((boost_plate_TL.y - boost_plate_BR.y) / 2) + boost_plate_BR.y);
00583     } else if(boost_plate.Type == 2) {
00584         //Calculates the coordinate of the point of the arrow drawn on the boost plate
00585         boost_plate_mid.x = (((boost_plate_BR.x - boost_plate_TL.x) / 2) + boost_plate_TL.x);
00586         boost_plate_mid.y = boost_plate_BR.y;
00587     } else if(boost_plate.Type == 3) {
00588         //Calculates the coordinate of the point of the arrow drawn on the boost plate
00589         boost_plate_mid.x = boost_plate_TL.x;
00590         boost_plate_mid.y = (((boost_plate_TL.y - boost_plate_BR.y) / 2) + boost_plate_BR.y);
00591     } else if(boost_plate.Type == 4) {
00592         //Calculates the coordinate of the point of the arrow drawn on the boost plate
00593         boost_plate_mid.x = (((boost_plate_BR.x - boost_plate_TL.x) / 2) + boost_plate_TL.x);
00594         boost_plate_mid.y = boost_plate_TL.y;
00595     }
00596 
00597     //Translation
00598     boost_plate_TL = Translate_Point(boost_plate_TL, Round(translation.x), Round(translation.y));
00599     boost_plate_TR = Translate_Point(boost_plate_TR, Round(translation.x), Round(translation.y));
00600     boost_plate_BL = Translate_Point(boost_plate_BL, Round(translation.x), Round(translation.y));
00601     boost_plate_BR = Translate_Point(boost_plate_BR, Round(translation.x), Round(translation.y));
00602     boost_plate_mid = Translate_Point(boost_plate_mid, Round(translation.x), Round(translation.y));
00603 
00604     //Rotation
00605     boost_plate_TL = Rotate_Point(boost_plate_TL, angle);
00606     boost_plate_TR = Rotate_Point(boost_plate_TR, angle);
00607     boost_plate_BL = Rotate_Point(boost_plate_BL, angle);
00608     boost_plate_BR = Rotate_Point(boost_plate_BR, angle);
00609     boost_plate_mid = Rotate_Point(boost_plate_mid, angle);
00610 
00611     //Squish
00612     boost_plate_TL = Squish_Point(boost_plate_TL, squish);
00613     boost_plate_TR = Squish_Point(boost_plate_TR, squish);
00614     boost_plate_BL = Squish_Point(boost_plate_BL, squish);
00615     boost_plate_BR = Squish_Point(boost_plate_BR, squish);
00616     boost_plate_mid = Squish_Point(boost_plate_mid, squish);
00617 
00618     //Draws the square edge of the boost plate
00619     Graphics_Draw_Line(boost_plate_TL, boost_plate_TR, true, LCD);
00620     Graphics_Draw_Line(boost_plate_TR, boost_plate_BR, true, LCD);
00621     Graphics_Draw_Line(boost_plate_BR, boost_plate_BL, true, LCD);
00622     Graphics_Draw_Line(boost_plate_BL, boost_plate_TL, true, LCD);
00623 
00624     //For each type of boost plate draw the arrow
00625     if(boost_plate.Type == 1) {
00626         Graphics_Draw_Line(boost_plate_TL, boost_plate_mid, true, LCD);
00627         Graphics_Draw_Line(boost_plate_BL, boost_plate_mid, true, LCD);
00628     } else if(boost_plate.Type == 2) {
00629         Graphics_Draw_Line(boost_plate_TL, boost_plate_mid, true, LCD);
00630         Graphics_Draw_Line(boost_plate_BL, boost_plate_mid, true, LCD);
00631     } else if(boost_plate.Type == 3) {
00632         Graphics_Draw_Line(boost_plate_TR, boost_plate_mid, true, LCD);
00633         Graphics_Draw_Line(boost_plate_BR, boost_plate_mid, true, LCD);
00634     } else if(boost_plate.Type == 4) {
00635         Graphics_Draw_Line(boost_plate_TR, boost_plate_mid, true, LCD);
00636         Graphics_Draw_Line(boost_plate_BR, boost_plate_mid, true, LCD);
00637     }
00638 
00639 }