Snake and Physics based jumping game with high scores and different difficulties.
Dependencies: N5110 SDFileSystem mbed
Diff: main.cpp
- Revision:
- 5:ae641b1d04fa
- Parent:
- 4:c2d920b17b14
--- a/main.cpp Wed Apr 27 12:43:34 2016 +0000 +++ b/main.cpp Wed May 04 15:01:20 2016 +0000 @@ -3,7 +3,7 @@ @file main.cpp @brief Program Implementation -@brief Revision 1.0 +@brief Revision 1.1 @author Joel W. Webb */ @@ -30,21 +30,23 @@ DirectionName direction; // current direction }; typedef struct JoyStick Joystick; -/// Joystick struct for storing data about default Joystick position and Current position +/// Global Joystick struct for storing data about default Joystick position and Current position Joystick joystick; + /// Ticker interrput for polling the joystick Ticker pollJoystick; /// Ticker for controlling refresh rate of games Ticker gametick; +/// Ticker for sctrolling the refresh rate of the display +Ticker screentick; /// File pointer for accessing SD card locations -FILE *fp; +FILE *fp = NULL; int main() { initInputs(); playSound(tune_intro); - // Initialise file pointer int snakeDifficulty = 1; int plinkDifficulty = 0; @@ -84,7 +86,7 @@ lcd.printString("No Results",0,0); wait(2.0); } else { // opened file so can write - while ( ! (g_buttonA_flag || g_buttonjoy_flag)) { + while ( ! (g_buttonA_flag | g_buttonjoy_flag)) { fscanf(fp,"%d",&stored_top_score); // ensure data type matches - note address operator (&) fclose(fp); // ensure you close the file after reading lcd.printString("Highscore:",10,0); @@ -108,6 +110,7 @@ // Selected Plink else if (select == 1) { + // If select = 3 or -1 then user has chosen 'Back' button while( !(select == 3 || select ==-1) ) { @@ -156,10 +159,7 @@ } } } - - sleep(); } - } @@ -310,10 +310,12 @@ // Appropriate strings printed to LCD lcd.printString("Game Over",20,0); - if (current_high_score != -1 && current_high_score < score) { + if (current_high_score == -2) { + lcd.printString("New High Score:",0,1); + } else if (current_high_score != -1 && current_high_score < score) { lcd.printString("New High Score",0,1); lcd.printString("Previously",0,3); - } else if (current_high_score != -1 && current_high_score > score) { + } else if (current_high_score != -1 && current_high_score >= score) { lcd.printString("Score",0,1); lcd.printString("High Score",0,3); } else { @@ -325,7 +327,7 @@ sprintf(buffer,"%d",score); lcd.printString(buffer,20,2); // Print previous high-score - if (current_high_score != -1) { + if (current_high_score != -1 && current_high_score != -2) { char str[14]; sprintf(str,"%d",current_high_score); lcd.printString(str,20,4); @@ -352,16 +354,19 @@ // Initialise plink variables pvar = initpvar(pvar); - // Game ticker int refreshRate = 100; float tickerDelay = 1.0/refreshRate; pvar.tickerDelay = tickerDelay; gametick.attach(&gametick_isr,tickerDelay); + // Update screen 30 fps + tickerDelay = 1.0/30.0; + screentick.attach(&screentick_isr,tickerDelay); wait(0.25); while(!pvar.gameOver) { if (g_gametick_flag) { + g_gametick_flag = 0; // Screen scrolling pvar = plinkScroll(pvar); @@ -381,10 +386,10 @@ gametick.detach(); lcd.clear(); - + // Handle high scores and printing game over messages to LCD pvar = plinkGameOver(pvar); - + } plinkvar initpvar(plinkvar pvar) @@ -526,7 +531,7 @@ default: error(); } - } + } // If the powerup has been missed then generate new one else if (pvar.powerUp.y > 47+pvar.powerUpRadius) { pvar.powerUp.x = rand()%(84-1-(pvar.powerUpRadius*2)) + pvar.powerUpRadius; @@ -571,75 +576,79 @@ } plinkvar plinkDrawScreen(plinkvar pvar) { - // Drawing on lcd - lcd.clear(); - // Drawing ball/blob - // If second blob stage - int noPlatform = 1; - if (pvar.ballRadius == 2) { + if (g_screentick_flag) { + g_screentick_flag = 0; + // Drawing on lcd + lcd.clear(); + // Print Current Score + char buffer[14]; + sprintf(buffer,"Score: %d",pvar.height); + lcd.printString(buffer,0,0); + // Drawing ball/blob + // If second blob stage + int noPlatform = 1; + if (pvar.ballRadius == 2) { + for (int i=0; i<20; i++) { + if ( (int)pvar.pos.y == (pvar.platforms[i].y - 2) && (int)pvar.pos.x > pvar.platforms[i].x-pvar.platformWidth-2 && (int)pvar.pos.x < pvar.platforms[i].x+pvar.platformWidth+2 ) { + noPlatform = 0; + lcd.drawRect(pvar.pos.x-2,pvar.pos.y-1,4,2,1); // X, Y, Width, Height, Fill + lcd.setPixel(pvar.pos.x-1,pvar.pos.y-2); + lcd.setPixel(pvar.pos.x,pvar.pos.y-2); + lcd.setPixel(pvar.pos.x+1,pvar.pos.y-2); + lcd.setPixel(pvar.pos.x-3,pvar.pos.y+1); + lcd.setPixel(pvar.pos.x+3,pvar.pos.y+1); + } + // If third blob stage + else if ( (int)pvar.pos.y == (pvar.platforms[i].y - 1) && (int)pvar.pos.x > pvar.platforms[i].x-pvar.platformWidth-2 && (int)pvar.pos.x < pvar.platforms[i].x+pvar.platformWidth+2 ) { + noPlatform = 0; + lcd.drawRect(pvar.pos.x-3,pvar.pos.y-1,6,1,1); // X, Y, Width, Height, Fill + lcd.setPixel(pvar.pos.x-4,pvar.pos.y); + lcd.setPixel(pvar.pos.x+4,pvar.pos.y); + lcd.setPixel(pvar.pos.x-2,pvar.pos.y-2); + lcd.setPixel(pvar.pos.x-1,pvar.pos.y-2); + lcd.setPixel(pvar.pos.x,pvar.pos.y-2); + lcd.setPixel(pvar.pos.x+1,pvar.pos.y-2); + lcd.setPixel(pvar.pos.x+2,pvar.pos.y-2); + } + } + } + // Else default blob stage + if (noPlatform == 1) { + lcd.drawCircle((int)pvar.pos.x,(int)pvar.pos.y,pvar.ballRadius,1); // X, Y, Radius, Fill + lcd.refresh(); + } + // Platforms and boundaries drawing for (int i=0; i<20; i++) { - if ( (int)pvar.pos.y == (pvar.platforms[i].y - 2) && (int)pvar.pos.x > pvar.platforms[i].x-pvar.platformWidth-2 && (int)pvar.pos.x < pvar.platforms[i].x+pvar.platformWidth+2 ) { - noPlatform = 0; - lcd.drawRect(pvar.pos.x-2,pvar.pos.y-1,4,2,1); // X, Y, Width, Height, Fill - lcd.setPixel(pvar.pos.x-1,pvar.pos.y-2); - lcd.setPixel(pvar.pos.x,pvar.pos.y-2); - lcd.setPixel(pvar.pos.x+1,pvar.pos.y-2); - lcd.setPixel(pvar.pos.x-3,pvar.pos.y+1); - lcd.setPixel(pvar.pos.x+3,pvar.pos.y+1); + if (pvar.platforms[i].y > 0) { + lcd.drawRect( pvar.platforms[i].x-pvar.platformWidth ,pvar.platforms[i].y,pvar.platformWidth*2,1,1); // X, Y, Width, Height, Fill } - // If third blob stage - else if ( (int)pvar.pos.y == (pvar.platforms[i].y - 1) && (int)pvar.pos.x > pvar.platforms[i].x-pvar.platformWidth-2 && (int)pvar.pos.x < pvar.platforms[i].x+pvar.platformWidth+2 ) { - noPlatform = 0; - lcd.drawRect(pvar.pos.x-3,pvar.pos.y-1,6,1,1); // X, Y, Width, Height, Fill - lcd.setPixel(pvar.pos.x-4,pvar.pos.y); - lcd.setPixel(pvar.pos.x+4,pvar.pos.y); - lcd.setPixel(pvar.pos.x-2,pvar.pos.y-2); - lcd.setPixel(pvar.pos.x-1,pvar.pos.y-2); - lcd.setPixel(pvar.pos.x,pvar.pos.y-2); - lcd.setPixel(pvar.pos.x+1,pvar.pos.y-2); - lcd.setPixel(pvar.pos.x+2,pvar.pos.y-2); - } + } + lcd.drawLine(0,0,0,47,1); // x0,y0,x1,y1,type + lcd.drawLine(83,0,83,47,1); + // PowerUp drawing + if (pvar.powerUp.y > 0-pvar.powerUpRadius && pvar.powerUp.y < 47+pvar.powerUpRadius) { + lcd.drawRect(pvar.powerUp.x-pvar.powerUpRadius,pvar.powerUp.y-pvar.powerUpRadius,10,10,0); // X, Y, Width, Height, Fill + lcd.setPixel(pvar.powerUp.x,pvar.powerUp.y+3); + lcd.setPixel(pvar.powerUp.x,pvar.powerUp.y+1); + lcd.setPixel(pvar.powerUp.x+1,pvar.powerUp.y); + lcd.setPixel(pvar.powerUp.x+2,pvar.powerUp.y-1); + lcd.setPixel(pvar.powerUp.x+2,pvar.powerUp.y-2); + lcd.setPixel(pvar.powerUp.x+1,pvar.powerUp.y-3); + lcd.setPixel(pvar.powerUp.x,pvar.powerUp.y-3); + lcd.setPixel(pvar.powerUp.x-1,pvar.powerUp.y-3); + lcd.setPixel(pvar.powerUp.x-2,pvar.powerUp.y-2); + } + + lcd.refresh(); + // Looks more pleasing when the ball pauses to bounce + if (noPlatform == 0) { + wait(0.03); } } - // Else default blob stage - if (noPlatform == 1) { - lcd.drawCircle((int)pvar.pos.x,(int)pvar.pos.y,pvar.ballRadius,1); // X, Y, Radius, Fill - lcd.refresh(); - } - // Platforms and boundaries drawing - for (int i=0; i<20; i++) { - if (pvar.platforms[i].y > 0) { - lcd.drawRect( pvar.platforms[i].x-pvar.platformWidth ,pvar.platforms[i].y,pvar.platformWidth*2,1,1); // X, Y, Width, Height, Fill - } - } - lcd.drawLine(0,0,0,47,1); // x0,y0,x1,y1,type - lcd.drawLine(83,0,83,47,1); - // PowerUp drawing - if (pvar.powerUp.y > 0-pvar.powerUpRadius && pvar.powerUp.y < 47+pvar.powerUpRadius) { - lcd.drawRect(pvar.powerUp.x-pvar.powerUpRadius,pvar.powerUp.y-pvar.powerUpRadius,10,10,0); // X, Y, Width, Height, Fill - lcd.setPixel(pvar.powerUp.x,pvar.powerUp.y+3); - lcd.setPixel(pvar.powerUp.x,pvar.powerUp.y+1); - lcd.setPixel(pvar.powerUp.x+1,pvar.powerUp.y); - lcd.setPixel(pvar.powerUp.x+2,pvar.powerUp.y-1); - lcd.setPixel(pvar.powerUp.x+2,pvar.powerUp.y-2); - lcd.setPixel(pvar.powerUp.x+1,pvar.powerUp.y-3); - lcd.setPixel(pvar.powerUp.x,pvar.powerUp.y-3); - lcd.setPixel(pvar.powerUp.x-1,pvar.powerUp.y-3); - lcd.setPixel(pvar.powerUp.x-2,pvar.powerUp.y-2); - } - - lcd.refresh(); - // Looks more pleasing when the ball pauses to bounce - if (noPlatform == 0) { - wait(0.03); - } - char buffer[14]; - sprintf(buffer,"Score: %d",pvar.height); - lcd.printString(buffer,0,0); - return pvar; } -plinkvar plinkGameOver(plinkvar pvar){ +plinkvar plinkGameOver(plinkvar pvar) +{ // Handle saving high scores to SD card // Read previous highscore if one exists fp = fopen("/sd/plinkhighscore.txt", "r"); @@ -665,11 +674,13 @@ // Appropriate strings printed to LCD lcd.printString("Game Over",20,0); - if (current_high_score != -1 && current_high_score < pvar.height) { + if (current_high_score == -2) { + lcd.printString("New High Score:",0,1); + } else if (current_high_score != -1 && current_high_score < pvar.height) { lcd.printString("New High Score",0,1); lcd.printString("Previously",0,3); - } else if (current_high_score != -1 && current_high_score > pvar.height) { - lcd.printString("Score",0,1); + } else if (current_high_score != -1 && current_high_score >= pvar.height) { + lcd.printString("Score:",0,1); lcd.printString("High Score",0,3); } else { lcd.printString("Score:",0,1); @@ -680,7 +691,7 @@ sprintf(buffer,"%d",pvar.height); lcd.printString(buffer,20,2); // Print previous high-score - if (current_high_score != -1) { + if (current_high_score != -1 && current_high_score != -2) { char str[14]; sprintf(str,"%d",current_high_score); lcd.printString(str,20,4); @@ -714,6 +725,10 @@ { g_gametick_flag = 1; } +void screentick_isr() +{ + g_screentick_flag = 1; +} // Initialises Inputs @@ -734,6 +749,7 @@ /// Testing LCD display works (splash screen) lcd.init(); wait(0.5); + lcd.setBrightness(0.5); // Brightness set to maximum duty cycle so it isn't affected by changing frequency of buzzer lcd.printString("Calibrating",8,0); lcd.printString("Do not move",8,1); lcd.printString("Joystick",18,2); @@ -743,14 +759,43 @@ calibrateJoystick(); /// read joystick 10 times per second pollJoystick.attach(&updateJoystick,1.0/10.0); - // Patch for sd casrd access not working first time - fp = fopen("sd/test.txt","w"); + + // Patch for sd card access not working first time + fp = fopen("/sd/test.txt", "w"); if (fp != NULL) { fclose(fp); } + fp = fopen("/sd/test.txt", "w"); + if (fp != NULL) { + fclose(fp); // ensure you close the file after writing + } + + // If file does not exist then create it + fp = fopen("/sd/plinkhighscore.txt","r"); + if (fp == NULL) { + fp = fopen("/sd/plinkhighscore.txt","w"); + if (fp != NULL) { + fprintf(fp,"%d",-2); + fclose(fp); + } + } else { + fclose(fp); + } + + fp = fopen("/sd/snakehighscore.txt","r"); + if (fp == NULL) { + fp = fopen("/sd/snakehighscore.txt","w"); + if (fp != NULL) { + fprintf(fp,"%d",-2); + fclose(fp); + } + } else { + fclose(fp); + } + wait(1.0); - lcd.clear(); } + // Hangs on an error void error() {