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.
Dependencies: mbed
Renderer.cpp
00001 #include "Renderer.h" 00002 00003 N5110 lcd(PTC9,PTC0,PTC7,PTD2,PTD1,PTC11); 00004 00005 Renderer::Renderer() { 00006 selectionCube.setVisible(); 00007 } 00008 00009 void Renderer::init() { 00010 lcd.init(); //initialize the lcd 00011 fov = 50; //set the field of view to 50 00012 } 00013 00014 00015 float Renderer::xTo2D(float x, float z) { //Project 3D x coordinate to 2D perspective 00016 return x * (fov/z) + 42; 00017 } 00018 00019 float Renderer::yTo2D(float y, float z){ //Project 3D y coordinate to 2D perspective 00020 return y * (fov/z) + 21; 00021 } 00022 00023 void Renderer::drawHorizon(float angle){ //draw the line at the horizon 00024 lcd.drawLine(0, 00025 21-rint(-angle*40), 00026 84, 00027 21+rint(-angle*40), 00028 1); 00029 } 00030 00031 void Renderer::drawFace(Face *face, float angle) { //Draw a single face from a cube 00032 float points[4][3]; 00033 float y, x; 00034 00035 for(int vertex = 0; vertex < 4; vertex++) { 00036 for(int axis = 0; axis < 3; axis++) { 00037 points[vertex][axis] = face->getVertexValue(vertex, axis); //copy all cube verticies to local array 00038 } 00039 y = points[vertex][1]; 00040 x = points[vertex][0]; 00041 00042 points[vertex][0] = x*cos(-angle)-y*sin(-angle); //perform temporary rotation for lean effect when moving in x axis 00043 points[vertex][1] = y*cos(-angle)+x*sin(-angle); 00044 } 00045 00046 if (checkOnScreen(points)){ //if face is on the screen then fill the face and draw its outline 00047 rasterizeFace(points, face); 00048 drawFaceOutline(points); 00049 } 00050 } 00051 00052 void Renderer::rasterizeFace(float (&points)[4][3], Face *face) { //Fill in the face using white lines 00053 int diffX1, diffY1, diffX2, diffY2; 00054 float stepBottomY, stepTopX, stepTopY; 00055 diffX1 = xTo2D(points[0][0], points[0][2])-xTo2D(points[1][0], 00056 points[1][2]); //Calculate difference between top horizontal edge x coordnates 00057 diffY1 = yTo2D(points[0][1], points[0][2])-yTo2D(points[1][1], 00058 points[1][2]); //Calculate difference between right vertical edge y coordinates 00059 diffX2 = xTo2D(points[2][0], points[2][2])-xTo2D(points[3][0], 00060 points[3][2]); //Calculate difference between bottom horizontal edge x coordinates 00061 diffY2 = yTo2D(points[2][1], points[2][2])-yTo2D(points[3][1], 00062 points[3][2]); //Calculate difference between left horizontal edge y coordinates 00063 if(diffX2 != 0) { 00064 stepBottomY = (float)diffY2/(float)diffX2; //increment multiplier for Y axis on bottom edge of face 00065 stepTopX = (float)diffX1/(float)diffX2; //increment multiplier for X axis on top edge of face 00066 stepTopY = (float)diffY1/(float)diffX2; //increment multiplier for Y axis on top edge of face 00067 00068 drawFillLines(points, diffX2, stepBottomY, stepTopX, stepTopY); //fill the face with white lines 00069 } 00070 } 00071 00072 void Renderer::drawFillLines(float (&points)[4][3], 00073 int diffX2, int stepBottomY, int stepTopX, int stepTopY) { //draw the white lines within the face to fill it in 00074 00075 for(int step = 0; step< abs(diffX2); step++) { 00076 if(diffX2 > 0) { //determine whether the face is inverted in y axis 00077 lcd.drawLine(rint(xTo2D(points[0][0], points[0][2])-stepTopX*step), //draw lines from top edge to bottom edge until face is filled in 00078 rint(yTo2D(points[0][1], points[0][2])-stepTopY*step), 00079 rint(xTo2D(points[3][0], points[3][2])+step), 00080 rint(yTo2D(points[3][1], points[3][2])+stepBottomY*step), 00081 0); 00082 } 00083 else { 00084 lcd.drawLine(rint(xTo2D(points[0][0], points[0][2])+stepTopX*step), 00085 rint(yTo2D(points[0][1], points[0][2])+stepTopY*step), 00086 rint(xTo2D(points[3][0], points[3][2])-step), 00087 rint(yTo2D(points[3][1], points[3][2])-stepBottomY*step), 00088 0); 00089 } 00090 } 00091 } 00092 00093 void Renderer::drawFaceOutline(float(&points)[4][3]) { //Draw the outline of the face 00094 for (int i = 0; i < 3; i++) { //cycle through each edge and draw them 00095 lcd.drawLine(rint(xTo2D(points[i][0], points[i][2])), 00096 rint(yTo2D(points[i][1], points[i][2])), 00097 rint(xTo2D(points[i+1][0], points[i+1][2])), 00098 rint(yTo2D(points[i+1][1], points[i+1][2])), 00099 1); 00100 } 00101 lcd.drawLine(rint(xTo2D(points[0][0], points[0][2])), 00102 rint(yTo2D(points[0][1], points[0][2])), 00103 rint(xTo2D(points[3][0], points[3][2])), 00104 rint(yTo2D(points[3][1], points[3][2])), 00105 1); 00106 } 00107 00108 void Renderer::drawAllFaces(Face *faceArray, int noOfCubes, float angle) { //draw all faces in game using the painters algorithm 00109 Face temp; 00110 for (int f = 0; f< (noOfCubes*6)-1; f++) { //sort the faces in decreasing average z value using bubble sort 00111 for (int f2 = 0; f2< (noOfCubes*6)-f-1; f2++) { 00112 if(faceArray[f2].getAvgZ() < faceArray[f2+1].getAvgZ()) { 00113 temp = faceArray[f2+1]; 00114 faceArray[f2+1] = faceArray[f2]; 00115 faceArray[f2] = temp; 00116 } 00117 } 00118 } 00119 for (int f = 0; f< noOfCubes*6 ; f++) { //draw each face from furthest away to closest 00120 if (faceArray[f].getVisible()) { 00121 drawFace(&faceArray[f], angle/15); 00122 } 00123 } 00124 } 00125 00126 bool Renderer::checkOnScreen(float (&points)[4][3]) { //Check whether any part of the face is on screen 00127 if (points[0][2] < 6 || points[1][2] < 6 || points[2][2] < 6 || 00128 points[3][2] < 6) { //not on screen if behind perspective 00129 return false; 00130 } 00131 else if ((xTo2D(points[0][0], points[0][2]) < 0 || xTo2D(points[0][0], 00132 points[0][2]) > 84) //check if any 2D projection verticies are within screen boundaries 00133 && (xTo2D(points[1][0], points[1][2]) < 0 || xTo2D(points[1][0], 00134 points[1][2]) > 84) 00135 && (xTo2D(points[2][0], points[2][2]) < 0 || xTo2D(points[2][0], 00136 points[2][2]) > 84) 00137 && (xTo2D(points[3][0], points[3][2]) < 0 || xTo2D(points[3][0], 00138 points[3][2]) > 84)){ 00139 return false; 00140 } 00141 return true; 00142 } 00143 00144 void Renderer::print(const char *text, int x, int y) { //print string at x, y position 00145 lcd.printString(text, x, y); 00146 } 00147 00148 void Renderer::printScore(int score, int x, int y) { //print a score at x, y position 00149 char buffer[5]; 00150 sprintf(buffer, "%d", score/3); 00151 print(buffer, x, y); 00152 memset(buffer, 0, sizeof buffer); 00153 } 00154 00155 void Renderer::clear() { //clear the display 00156 lcd.clear(); 00157 } 00158 00159 void Renderer::refresh() { //refresh display and wait for 1/60th second (target fps = 60) 00160 lcd.refresh(); 00161 wait_ms(1000/60); 00162 } 00163 00164 void Renderer::turnOff() { //turn off the display 00165 lcd.turnOff(); 00166 } 00167 00168 void Renderer::setContrast(float contrast) { //set the contrast of the display 00169 lcd.setContrast(contrast); 00170 } 00171 00172 void Renderer::drawDeathScreen(int selection, int highScore) { //draw the screen once the user has collided with cube 00173 Face faces[6]; 00174 int x, y, z; 00175 if(selection == 0){ //determine position of seleciton cube based on menu selection 00176 x = -30; 00177 y = -3; 00178 z = 50; 00179 } 00180 else{ 00181 x = -30; 00182 y = 15; 00183 z = 50; 00184 } 00185 00186 print("Best:", 30, 0); //print high score 00187 printScore(highScore, 60, 0); 00188 drawDeathButtons(); 00189 drawSelectionCube(x, y, z, 2); 00190 } 00191 00192 void Renderer::drawDeathButtons() {//draw the death screen buttons 00193 lcd.drawRect(24, 14, 45, 11, FILL_WHITE); 00194 lcd.drawRect(24, 14, 45, 11, FILL_TRANSPARENT); 00195 lcd.printString("Restart",26,2); 00196 lcd.drawRect(24, 30, 45, 11, FILL_WHITE); 00197 lcd.drawRect(24, 30, 45, 11, FILL_TRANSPARENT); 00198 lcd.printString("Menu",35,4); 00199 } 00200 00201 void Renderer::drawHomeScreen(int selection) { //draw the home screen 00202 int x, y, z; 00203 if(selection == 0) { //determine position of selection cube based on home screen selection 00204 x = -30; 00205 y = -12; 00206 z = 50; 00207 } 00208 else if(selection == 1) { 00209 x = -30; 00210 y = 5; 00211 z = 50; 00212 } 00213 else { 00214 x = -30; 00215 y = 22; 00216 z = 50; 00217 } 00218 drawHomeButtons(); 00219 drawSelectionCube(x, y, z, -1); 00220 } 00221 00222 void Renderer::drawHomeButtons() { //draw home screen buttons 00223 lcd.drawRect(24, 6, 45, 10, FILL_WHITE); 00224 lcd.printString("Play",35,1); 00225 lcd.drawRect(24, 6, 45, 10, FILL_TRANSPARENT); 00226 00227 lcd.drawRect(24, 22, 45, 10, FILL_WHITE); 00228 lcd.printString("Help",35,3); 00229 lcd.drawRect(24, 22, 45, 10, FILL_TRANSPARENT); 00230 00231 lcd.drawRect(24, 38, 45, 10, FILL_WHITE); 00232 lcd.printString("Quit",35,5); 00233 lcd.drawRect(24, 38, 45, 10, FILL_TRANSPARENT); 00234 } 00235 00236 void Renderer::drawSelectionCube(int x, int y, int z, int rotationSpeed) { //draw the seleciton cube 00237 Face faces[6]; 00238 selectionCube.translate(x, y, z); //translate from origin to required position 00239 00240 for(int i = 0; i < 6; i++) { 00241 faces[i] = selectionCube.getFace(i); 00242 } 00243 drawAllFaces(faces, 1, 0); //draw all faces of the cube 00244 selectionCube.translate(-x, -y, -z); //translate back to origin 00245 selectionCube.rotateX(-0.05*rotationSpeed); //rotate the cube 00246 selectionCube.rotateY(-0.025*rotationSpeed); 00247 selectionCube.rotateZ(0.04*rotationSpeed); 00248 } 00249 00250 void Renderer::drawHelpScreen1() { //draw the first help screen 00251 lcd.printString("Use the",20,0); 00252 lcd.printString("joystick",17,1); 00253 lcd.printString("to move",20,2); 00254 lcd.printString("left and right.",0,3); 00255 lcd.printString("(Press B)",17,5); 00256 } 00257 00258 void Renderer::drawHelpScreen2(){ //draw the second help screen 00259 lcd.printString("Dodge the",15,0); 00260 lcd.printString("cubes as they",3,1); 00261 lcd.printString("move closer",10,2); 00262 lcd.printString("to you",25,3); 00263 lcd.printString("(Press B)",17,5); 00264 } 00265 00266 void Renderer::drawHelpScreen3(){ //draw the third help screen 00267 lcd.printString("Even the",17,0); 00268 lcd.printString("smallest",17,1); 00269 lcd.printString("touch can",15,2); 00270 lcd.printString("kill you",17,3); 00271 lcd.printString("(Press B)",17,5); 00272 } 00273 00274 void Renderer::drawHelpScreen4(){ //draw the fourth help screen 00275 lcd.printString("Good luck!",15,1); 00276 lcd.printString("(Press B)",17,5); 00277 }
Generated on Fri Jul 15 2022 03:54:57 by
1.7.2