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: N5110 mbed PowerControl
main.cpp
00001 /** 00002 @file main.cpp 00003 @brief Source file for main game containing function defintions and main loop. 00004 @autor Thomas Davies 00005 @date May 2015 00006 */ 00007 00008 #include "main.h" 00009 00010 00011 int main() 00012 { 00013 DigitalOut backLight(p26); 00014 backLight.write(1); 00015 lcd.Initialize(); 00016 powerSave(); 00017 00018 lcd.displayStartScreen(); 00019 while(!isRight()) {} //wait until right button pressed 00020 00021 wait(0.5); //just to ignore layover from first button press. 00022 00023 lcd.displayInstructionScreen(); 00024 while(!isRight()) {} //wait until right button pressed. 00025 00026 wait(0.5); 00027 lcd.displayInstructionScreen2(); 00028 while(!isRight()) {} //wait until right button pressed. 00029 00030 lcd.displayCountdown(); 00031 lcd.clear(); 00032 00033 bool refresh = false; 00034 00035 lcd.drawAllPlatforms(); 00036 lcd.drawBall(); 00037 lcd.refresh(); 00038 00039 gameClock.attach(&clockCounter,0.003); //attach the master clock! 00040 00041 //MAIN GAME LOOP 00042 //multiple runs on a single loop. stop with a bool 00043 00044 char buffer[10]; 00045 while(true) { 00046 if (isFirstCheck) { //if first time checking this clock cycle. 00047 if(clockCount %(gameSpeed) == 0) { 00048 //advance platforms 00049 advancePlatforms(numPixelsToJump); 00050 numPlatformShifts ++; 00051 00052 if (numPlatformShifts%5 == 0) { 00053 gameLevel ++; 00054 } 00055 refresh = true; 00056 } 00057 00058 if(clockCount%14 == 0) { 00059 //ball movement 00060 if (isLeft() && isBallDirClear(1)) { //if josystick left and direction is clear 00061 lcd.eraseBall(); 00062 lcd.setBallPos(lcd.getBallX ()+2,lcd.getBallY ()); 00063 refresh = true; 00064 00065 } else if (isRight() && isBallDirClear(0)) { 00066 lcd.eraseBall(); 00067 lcd.setBallPos(lcd.getBallX ()-2,lcd.getBallY ()); 00068 refresh = true; 00069 } 00070 } 00071 00072 //if the ball is in free space, animate it falling! 00073 if (clockCount%(10/numPixelsToJump) == 0) { 00074 if(isBallFalling(lcd.getBallY ())) { 00075 lcd.eraseBall(); 00076 lcd.setBallPos(lcd.getBallX (),lcd.getBallY () + numPixelsToJump); 00077 refresh = true; 00078 isFirstHit = true; 00079 } 00080 } 00081 00082 if ((clockCount%(-45*gameSpeed + 2045) == 0)) { //starting levels are quick to progress, later slower. 00083 if (isFirstSpeedUp) //skip first accepted modulus! 00084 isFirstSpeedUp = false; 00085 else { 00086 gameSpeed --; 00087 isFirstSpeedUp = true; 00088 } 00089 } 00090 00091 if (joystickButton.read()) { //pause menu! 00092 int oldClock = clockCount; //save the clock count! 00093 pauseScreenController(); 00094 clockCount = oldClock; 00095 wait(0.3); 00096 lcd.clear(); 00097 refresh = true; 00098 } 00099 00100 if (refresh) { 00101 lcd.drawBall(); 00102 lcd.drawAllPlatforms(); 00103 00104 sprintf(buffer,"lvl:%d",gameLevel); 00105 lcd.printString(buffer,lcd.getMaxX () - 2,-1); 00106 lcd.refresh(); 00107 refresh = false; 00108 } 00109 00110 00111 //check if ball hit roof 00112 if (lcd.getBallY () == 7) { 00113 break; 00114 } 00115 00116 00117 isFirstCheck = false; 00118 } 00119 } 00120 00121 gameClock.detach(); 00122 00123 lcd.clear(); 00124 00125 endScreenController(); 00126 return 1; 00127 } 00128 00129 00130 //#############FUNCTION DEFINITIONS#################// 00131 void advancePlatforms(int n) 00132 { 00133 //ADVANCE 00134 lcd.eraseAllPlatforms(); 00135 lcd.shiftAllPlatforms(n); 00136 lcd.drawAllPlatforms(); 00137 00138 //if ball is on platform 00139 if(!isBallFalling(lcd.getBallY ()-n)) { 00140 //auditory feedback if first collision 00141 if (isFirstHit) { 00142 boop(); 00143 isFirstHit = false; 00144 } 00145 //move ball up with platform 00146 lcd.eraseBall(); 00147 lcd.setBallPos(lcd.getBallX (),lcd.getBallY () -n); 00148 } 00149 00150 00151 } 00152 00153 bool isBallFalling(int bY) 00154 { 00155 int bX = lcd.getBallX (); //ball X pos 00156 int bR = lcd.getBallR (); //ball radius 00157 00158 //find next platform lower than ball 00159 //check Y pos to see if ball is on platform, return false if on plat 00160 //check X pos to see if ball is over gap, return true if over gap 00161 Platform closestPlatform = lcd.nextClosestPlatform(bY - bR); 00162 00163 00164 //if bottom of ball on level of platform 00165 if ((bY+bR) == (closestPlatform.y)) { 00166 if (bX > closestPlatform.x && (bX+bR-1) < (closestPlatform.x + lcd.getPlatGapSize ())) { //OVER GAP 00167 return true; 00168 } else { 00169 return false; 00170 } //On platform! 00171 } else if ((bY+bR) >= (lcd.getMaxY ()-1)) { 00172 return false; 00173 } else //FREE SPACE 00174 return true; 00175 } 00176 00177 00178 bool isBallDirClear(int dir) 00179 { 00180 Platform closestPlatform = lcd.nextClosestPlatform(lcd.getBallY () - lcd.getBallR ()+2); 00181 00182 int ballRight = lcd.getBallX (); 00183 int ballLeft = ballRight+lcd.getBallR (); 00184 int ballTop = lcd.getBallY (); 00185 int ballBottom = ballTop + lcd.getBallR (); 00186 00187 if (dir == 1) { 00188 if (ballBottom > closestPlatform.y) //is ball inside a gap in platform? 00189 if (ballLeft >= (closestPlatform.x+lcd.getPlatGapSize ())) //is the ball next to gap wall? 00190 return false; 00191 if (ballLeft < lcd.getMaxX ()) { //is ball next to left hand wall? 00192 return true; 00193 } 00194 } else if (dir == 0) { 00195 if (ballBottom > closestPlatform.y) //is ball inside a gap in platform? 00196 if (ballRight <= closestPlatform.x) 00197 return false; 00198 00199 if (ballRight > 0) { //right hand wall check 00200 return true; 00201 } 00202 } 00203 return false; 00204 } 00205 00206 bool isRight() 00207 { 00208 double count = 0.0; 00209 double total = 0.0; 00210 //obtain an average to negate outliers 00211 while (count < 10) { 00212 count ++; 00213 total += joystickX.read(); 00214 } 00215 if ((total/count)> 0.8) 00216 return true; 00217 00218 return false; 00219 } 00220 00221 bool isLeft() 00222 { 00223 double count = 0.0; 00224 double total = 0.0; 00225 //obtain an average to negate outliers 00226 while (count < 10) { 00227 count ++; 00228 total += joystickX.read(); 00229 } 00230 if ((total/count) < 0.2) 00231 return true; 00232 00233 return false; 00234 } 00235 00236 bool isUp() 00237 { 00238 double count = 0.0; 00239 double total = 0.0; 00240 //obtain an average to negate outliers 00241 while (count < 10) { 00242 count ++; 00243 total += joystickY.read(); 00244 } 00245 00246 if ((total/count) < 0.2) 00247 return true; 00248 00249 return false; 00250 } 00251 bool isDown() 00252 { 00253 double count = 0.0; 00254 double total = 0.0; 00255 //obtain an average to negate outliers 00256 while (count < 10) { 00257 count ++; 00258 total += joystickY.read(); 00259 } 00260 if ((total/count) > 0.8) 00261 return true; 00262 00263 return false; 00264 } 00265 00266 void clockCounter () 00267 { 00268 //increment clock count! 00269 clockCount ++; 00270 isFirstCheck = true; 00271 } 00272 00273 void endScreenController() 00274 { 00275 int cursorLoc = 0; 00276 //cursor location array. 00277 int cursorArray[3][3] = { 00278 {1,0,0}, 00279 {0,1,0}, 00280 {0,0,1} 00281 }; 00282 00283 //check if user achieved high score 00284 bool record = isRecord(); 00285 00286 //if not a record move mouse start to second option 00287 if (!record) 00288 cursorLoc = 1; 00289 00290 lcd.displayEndScreen(gameLevel,cursorArray[cursorLoc],record); 00291 bool change = false; 00292 00293 while (true) { 00294 if (isUp()) { 00295 cursorLoc ++; //advance cursor menu 00296 change = true; 00297 } else if (isDown()) { 00298 cursorLoc --; //move back cursor menu 00299 change = true; 00300 } 00301 00302 //cyclical cursor management 00303 if (cursorLoc == 3) 00304 cursorLoc = 1-record; 00305 else if (cursorLoc == (-record)) 00306 cursorLoc = 2; 00307 00308 //if theres a change to buffer, show it 00309 if (change) { 00310 lcd.displayEndScreen(gameLevel,cursorArray[cursorLoc],record); 00311 wait(0.5); 00312 change = false; 00313 } 00314 00315 //menu selection manager 00316 if (joystickButton.read()) { 00317 switch(cursorLoc) { 00318 case 0: 00319 //take to initial entry page! (only allow if score > top 3) 00320 wait(0.3); 00321 highScoreEditor(recordEntryController(),record); 00322 00323 wait(1); 00324 //reset once button pressed! 00325 while(!joystickButton.read()) {} 00326 mbed_reset(); 00327 break; 00328 case 1: 00329 //take to high score page! 00330 highScoreEditor("",0); 00331 wait(1); 00332 //reset once button pressed. 00333 while(!joystickButton.read()) {} 00334 mbed_reset(); 00335 break; 00336 case 2: 00337 //restart 00338 mbed_reset(); 00339 break; 00340 } 00341 } 00342 } 00343 } 00344 00345 char* recordEntryController() 00346 { 00347 //array of letters to traverse 00348 char *letters = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"}; 00349 00350 //array of ints, each corresponding to letter in letters array 00351 int ptr[3] = {0,0,0}; 00352 00353 //cursor management variables 00354 int cursorLoc = 0; 00355 int cursorArray[3][3] = { 00356 {1,0,0}, 00357 {0,1,0}, 00358 {0,0,1} 00359 }; 00360 00361 lcd.displayRecordScreen(cursorArray[cursorLoc],letters[ptr[0]],letters[ptr[1]],letters[ptr[2]]); 00362 00363 bool change = false; 00364 00365 while (true) { 00366 if (isUp()) { 00367 cursorLoc ++; 00368 change = true; 00369 } else if (isDown()) { 00370 cursorLoc --; 00371 change = true; 00372 } else if (isLeft()) { 00373 //cyclical letter management 00374 if (ptr[cursorLoc] == 0) 00375 ptr[cursorLoc] = 25; //last letter 00376 else 00377 ptr[cursorLoc] --; //previous letter 00378 change = true; 00379 } else if (isRight()) { 00380 if (ptr[cursorLoc] == 25) 00381 ptr[cursorLoc] = 0; //first letter 00382 else 00383 ptr[cursorLoc] ++; //next letter 00384 change = true; 00385 } 00386 00387 //cyclical mouse management 00388 if (cursorLoc == 3) 00389 cursorLoc = 0; 00390 else if (cursorLoc == -1) 00391 cursorLoc = 2; 00392 00393 if (change) { 00394 lcd.displayRecordScreen(cursorArray[cursorLoc],letters[ptr[0]],letters[ptr[1]],letters[ptr[2]]); 00395 wait(0.2); 00396 change = false; 00397 } 00398 00399 if (joystickButton.read()) { 00400 //go to high score screen 00401 static char initials[10]; 00402 sprintf(initials,"%c%c%c",letters[ptr[0]],letters[ptr[1]],letters[ptr[2]]); 00403 return initials; 00404 } 00405 } 00406 } 00407 00408 void highScoreEditor(char *playerInitials,bool isRecord) 00409 { 00410 //check if lvl is in top 3 00411 FILE *fp = fopen("/local/scores.csv","r"); //open for reading. 00412 00413 char s_hs0[3],s_hs1[3],s_hs2[3]; 00414 int d_hs[3]; 00415 00416 //if file exists, parse it 00417 if (fp != NULL) { 00418 00419 char buffer[2]; 00420 00421 fscanf(fp,"%3s,%s",s_hs0,buffer); 00422 d_hs[0] = atoi(buffer); 00423 fscanf(fp,"%3s,%s",s_hs1,buffer); 00424 d_hs[1] = atoi(buffer); 00425 fscanf(fp,"%3s,%s",s_hs2,buffer); 00426 d_hs[2] = atoi(buffer); 00427 00428 fclose(fp); 00429 } 00430 //else set arbitrary values! 00431 else { 00432 d_hs[0] = 0; 00433 d_hs[1] = 0; 00434 d_hs[2] = 0; 00435 00436 strcpy(s_hs0,"---"); 00437 strcpy(s_hs1,"---"); 00438 strcpy(s_hs2,"---"); 00439 } 00440 00441 if (isRecord) { 00442 00443 if (gameLevel >= d_hs[2]) { 00444 d_hs[2] = gameLevel; 00445 strncpy(s_hs2,playerInitials,3); 00446 } 00447 if (gameLevel >= d_hs[1]) { 00448 d_hs[2] = d_hs[1]; 00449 d_hs[1] = gameLevel; 00450 strncpy(s_hs2,s_hs1,3); 00451 strncpy(s_hs1,playerInitials,3); 00452 } 00453 if (gameLevel >= d_hs[0]) { 00454 d_hs[1] = d_hs[0]; 00455 d_hs[0] = gameLevel; 00456 strncpy(s_hs1,s_hs0,3); 00457 strncpy(s_hs0,playerInitials,3); 00458 } 00459 00460 char buffer[40]; 00461 sprintf(buffer,"%s,%d\n%s,%d\n%s,%d",s_hs0,d_hs[0],s_hs1,d_hs[1],s_hs2,d_hs[2]); 00462 fp = fopen("/local/scores.csv","w"); 00463 fprintf(fp,buffer); 00464 fclose(fp); 00465 } 00466 00467 lcd.displayHighScores(s_hs0,s_hs1,s_hs2,d_hs); 00468 } 00469 00470 bool isRecord () 00471 { 00472 //check if lvl is in top 3 00473 FILE *fp = fopen("/local/scores.csv","r"); //open for reading. 00474 00475 //if file doesn't exist, then player has a highscore! 00476 if (fp == NULL) 00477 return true; 00478 00479 int highScore; 00480 char buffer[2]; 00481 char temp[3]; 00482 00483 for (int i = 0; i < 3; i++) { 00484 fscanf(fp,"%3s,%s",temp,buffer); 00485 highScore = atoi(buffer); 00486 if (gameLevel > highScore) { 00487 fclose (fp); 00488 return 1; 00489 } 00490 } 00491 fclose(fp); 00492 return 0; 00493 } 00494 00495 void boop () 00496 { 00497 if (isSound == 'Y') { 00498 buzzer.write(1); 00499 lowFlipper.attach_us(&pwmLow,pwmCount); 00500 } 00501 } 00502 00503 void pwmLow() 00504 { 00505 if (pwmCount != 4000) { 00506 buzzer.write(0); 00507 highFlipper.attach_us(&boop,pwmCount); 00508 pwmCount += 50; 00509 } else 00510 pwmCount = 1000; 00511 00512 } 00513 00514 //can toggle sound or quit game. 00515 void pauseScreenController() 00516 { 00517 int cursorLoc = 0; 00518 int cursorArray[3][3] = { 00519 {1,0,0}, 00520 {0,1,0}, 00521 {0,0,1} 00522 }; 00523 00524 lcd.displayPauseScreen(cursorArray[cursorLoc],isSound); 00525 00526 bool change = false; 00527 bool resume = false; 00528 00529 while (!resume) { 00530 if (isUp()) { 00531 cursorLoc ++; 00532 change = true; 00533 } else if (isDown()) { 00534 cursorLoc --; 00535 change = true; 00536 } else if (isLeft() || isRight()) { 00537 if (isSound == 'Y') 00538 isSound = 'N'; 00539 else 00540 isSound = 'Y'; 00541 change = true; 00542 } 00543 00544 //cyclical mouse management 00545 if (cursorLoc == 3) 00546 cursorLoc = 0; 00547 else if (cursorLoc == -1) 00548 cursorLoc = 2; 00549 00550 if (change) { 00551 lcd.displayPauseScreen(cursorArray[cursorLoc],isSound); 00552 wait(0.2); 00553 change = false; 00554 } 00555 00556 if (joystickButton.read()) { 00557 switch (cursorLoc) { 00558 case 1: 00559 mbed_reset(); 00560 break; 00561 case 2: 00562 resume = true; 00563 break; 00564 default: 00565 break; 00566 } 00567 } 00568 } 00569 } 00570 00571 void powerSave() 00572 { 00573 PHY_PowerDown(); //power down ethernet 00574 //mbed automatically manages peripheral power, no need to manually disable each 00575 }
Generated on Thu Jul 14 2022 20:38:02 by
1.7.2