ELEC2645 (2015/16) / Mbed 2 deprecated SnakeProjectRev1

Dependencies:   Joystick N5110 SDFileSystem beep fsmMenu mbed

Fork of SnakeProjectRev1 by Meurig Phillips

Committer:
meurigp
Date:
Thu May 05 14:19:50 2016 +0000
Revision:
21:e03461ea23e9
Parent:
20:f634b1060981
Child:
22:195d66c61bf3
neater code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
meurigp 15:a5590211888c 1 /**
meurigp 15:a5590211888c 2 @file main.cpp
meurigp 10:7820b46476ea 3
meurigp 15:a5590211888c 4 @brief Program implementation of Snake Game
meurigp 15:a5590211888c 5
meurigp 15:a5590211888c 6 */
meurigp 0:fcb5a32bc2fc 7
meurigp 11:f8478bc749e0 8 #include "main.h"
meurigp 0:fcb5a32bc2fc 9
meurigp 21:e03461ea23e9 10 // Serial for debug
meurigp 12:825a402d230f 11 Serial serial(USBTX,USBRX);
meurigp 0:fcb5a32bc2fc 12
meurigp 9:6d7074258c63 13 FILE *fp; // this is our file pointer
meurigp 6:9a5706a27240 14
meurigp 21:e03461ea23e9 15
meurigp 9:6d7074258c63 16
meurigp 14:56e355c5cfc9 17 int main()
meurigp 14:56e355c5cfc9 18 {
meurigp 0:fcb5a32bc2fc 19 calibrateJoystick(); // get centred values of joystick
meurigp 8:9b767dd1e549 20 pollJoystick.attach(&updateJoystick,0.5/10.0); // read joystick 20 times per second
meurigp 2:663b9aadf00c 21
meurigp 2:663b9aadf00c 22 srand(time(NULL));
meurigp 9:6d7074258c63 23
meurigp 9:6d7074258c63 24 greenLed = 1;
meurigp 9:6d7074258c63 25 redLed = 0;
meurigp 0:fcb5a32bc2fc 26 lcd.init();
meurigp 20:f634b1060981 27 snakeIntro();
meurigp 16:68b9460d4c76 28 gamePlaying = false;
meurigp 14:56e355c5cfc9 29 button.rise(&buttonISR);
meurigp 14:56e355c5cfc9 30 gameTicker.attach(&timer_isr,0.1);
meurigp 16:68b9460d4c76 31 RB.mode(PullDown);
meurigp 16:68b9460d4c76 32 LB.mode(PullDown);
meurigp 16:68b9460d4c76 33 RB.rise(&rb_isr);
meurigp 16:68b9460d4c76 34 LB.rise(&lb_isr);
meurigp 16:68b9460d4c76 35
meurigp 16:68b9460d4c76 36
meurigp 19:8907a82ebe09 37 mainMenu();
meurigp 0:fcb5a32bc2fc 38
meurigp 0:fcb5a32bc2fc 39 }
meurigp 0:fcb5a32bc2fc 40
meurigp 20:f634b1060981 41 void mainGame() {
meurigp 20:f634b1060981 42
meurigp 20:f634b1060981 43 if(gameType == classicMode) {
meurigp 20:f634b1060981 44 hardWall();
meurigp 20:f634b1060981 45 i = 41;
meurigp 20:f634b1060981 46 j = 23;
meurigp 20:f634b1060981 47 }
meurigp 20:f634b1060981 48 else if(gameType == infiniteMode) {
meurigp 20:f634b1060981 49 wrapAround();
meurigp 20:f634b1060981 50 i = 40;
meurigp 20:f634b1060981 51 j = 22;
meurigp 20:f634b1060981 52 }
meurigp 20:f634b1060981 53 else {
meurigp 20:f634b1060981 54 specialMap();
meurigp 20:f634b1060981 55 i = 13;
meurigp 20:f634b1060981 56 j = 5;
meurigp 20:f634b1060981 57 }
meurigp 20:f634b1060981 58 generateFood();
meurigp 20:f634b1060981 59 initSnakeTail();
meurigp 20:f634b1060981 60 snakeTailLength = 3;
meurigp 20:f634b1060981 61 score = 0;
meurigp 20:f634b1060981 62 fruitValue = 10;
meurigp 20:f634b1060981 63 pauseCount = 0; // init everything
meurigp 20:f634b1060981 64
meurigp 20:f634b1060981 65 while(gamePlaying == true) {
meurigp 20:f634b1060981 66
meurigp 20:f634b1060981 67 lcd.setBrightness(1-pot); // turn pot right for brightness
meurigp 20:f634b1060981 68
meurigp 20:f634b1060981 69 if (buttonFlag ==1) {
meurigp 20:f634b1060981 70 buttonFlag = 0;
meurigp 20:f634b1060981 71 if (pauseCount < 3) {
meurigp 20:f634b1060981 72 gamePaused();
meurigp 20:f634b1060981 73 }
meurigp 20:f634b1060981 74 buttonFlag = 0;
meurigp 20:f634b1060981 75 }
meurigp 20:f634b1060981 76 buttonFlag = 0;
meurigp 20:f634b1060981 77
meurigp 20:f634b1060981 78 if(game_timer_flag) {
meurigp 20:f634b1060981 79 game_timer_flag = 0;
meurigp 20:f634b1060981 80 gameLogic();
meurigp 20:f634b1060981 81 }
meurigp 20:f634b1060981 82 if (printFlag) { // if flag set, clear flag and print joystick values to serial port
meurigp 20:f634b1060981 83 printFlag = 0;
meurigp 20:f634b1060981 84 moveSnake();
meurigp 20:f634b1060981 85 }
meurigp 20:f634b1060981 86 sleep(); // put the MCU to sleep until an interrupt wakes it up
meurigp 20:f634b1060981 87 }
meurigp 20:f634b1060981 88 }
meurigp 20:f634b1060981 89
meurigp 20:f634b1060981 90 void mainMenu() {
meurigp 20:f634b1060981 91
meurigp 20:f634b1060981 92 while(1) {
meurigp 20:f634b1060981 93
meurigp 20:f634b1060981 94 lcd.printString("Classic",0,1);
meurigp 20:f634b1060981 95 lcd.printString("Infinite",0,3);
meurigp 20:f634b1060981 96 lcd.printString("Hard Map",0,5);
meurigp 20:f634b1060981 97
meurigp 20:f634b1060981 98 if (rb_flag == 1) {
meurigp 20:f634b1060981 99 rb_flag = 0;
meurigp 20:f634b1060981 100 gamePlaying = true;
meurigp 20:f634b1060981 101 mainGame();
meurigp 20:f634b1060981 102 }
meurigp 20:f634b1060981 103
meurigp 20:f634b1060981 104 // check if flag i.e. interrupt has occured
meurigp 20:f634b1060981 105 if (printFlag ==1) {
meurigp 20:f634b1060981 106 printFlag = 0; // if it has, clear the flag
meurigp 20:f634b1060981 107
meurigp 20:f634b1060981 108 // swap direction when button has been pressed
meurigp 20:f634b1060981 109 // (could just use ! but want this to be explicit to aid understanding)
meurigp 20:f634b1060981 110 if (joystick.direction == CENTRE) {
meurigp 20:f634b1060981 111 serial.printf(" CENTRE\n");
meurigp 20:f634b1060981 112 menuDirection = menuSTOP;
meurigp 20:f634b1060981 113 }
meurigp 20:f634b1060981 114 else if (joystick.direction == UP) {
meurigp 20:f634b1060981 115 serial.printf(" UP\n");
meurigp 20:f634b1060981 116 menuDirection = menuUP;
meurigp 20:f634b1060981 117 buzzer.beep(2000,0.2);
meurigp 20:f634b1060981 118 }
meurigp 20:f634b1060981 119 else if (joystick.direction == DOWN) {
meurigp 20:f634b1060981 120 serial.printf(" DOWN\n");
meurigp 20:f634b1060981 121 menuDirection = menuDOWN;
meurigp 20:f634b1060981 122 buzzer.beep(2000,0.2);
meurigp 20:f634b1060981 123 }
meurigp 20:f634b1060981 124 }
meurigp 20:f634b1060981 125
meurigp 20:f634b1060981 126
meurigp 20:f634b1060981 127 menuFSM();
meurigp 20:f634b1060981 128
meurigp 20:f634b1060981 129
meurigp 20:f634b1060981 130 wait(0.2); // small delay
meurigp 20:f634b1060981 131 if (state ==0) {
meurigp 20:f634b1060981 132 lcd.clear();
meurigp 20:f634b1060981 133 lcd.printString("*",70,1);
meurigp 20:f634b1060981 134 gameType = classicMode;
meurigp 20:f634b1060981 135 }
meurigp 20:f634b1060981 136 else if (state ==1) {
meurigp 20:f634b1060981 137 lcd.clear();
meurigp 20:f634b1060981 138 lcd.printString("*",70,3);
meurigp 20:f634b1060981 139 gameType = infiniteMode;
meurigp 20:f634b1060981 140 }
meurigp 20:f634b1060981 141 else if (state ==2) {
meurigp 20:f634b1060981 142 lcd.clear();
meurigp 20:f634b1060981 143 lcd.printString("*",70,5);
meurigp 20:f634b1060981 144 gameType = hardMode;
meurigp 20:f634b1060981 145 }
meurigp 20:f634b1060981 146
meurigp 20:f634b1060981 147 }
meurigp 20:f634b1060981 148
meurigp 20:f634b1060981 149 }
meurigp 4:3ceebacef5f1 150
meurigp 2:663b9aadf00c 151 void generateFood()
meurigp 1:97ac723959f2 152 {
meurigp 17:4e6f0f7f22fb 153 if (gameType == classicMode || gameType == hardMode) {
meurigp 17:4e6f0f7f22fb 154 while (randomXoddEven ==0 || randomYoddEven ==0 || lcd.getPixel(randomX,randomY) >= 1) { // do while x or y is even or pixel is on
meurigp 17:4e6f0f7f22fb 155
meurigp 17:4e6f0f7f22fb 156 randomX = rand() % 83 + 1; // randomX in the range 1 to 83
meurigp 17:4e6f0f7f22fb 157 randomY = rand() % 47 + 1; // randomY in the range 1 to 47
meurigp 17:4e6f0f7f22fb 158 randomXoddEven = randomX%2; // find out whether odd or even
meurigp 17:4e6f0f7f22fb 159 randomYoddEven = randomY%2;
meurigp 17:4e6f0f7f22fb 160 }
meurigp 17:4e6f0f7f22fb 161
meurigp 17:4e6f0f7f22fb 162 lcd.drawRect(randomX,randomY,1,1,1);
meurigp 17:4e6f0f7f22fb 163 }
meurigp 17:4e6f0f7f22fb 164
meurigp 17:4e6f0f7f22fb 165 else {
meurigp 17:4e6f0f7f22fb 166 while (randomXoddEven ==1 || randomYoddEven ==1 || lcd.getPixel(randomX,randomY) >= 1) { // do while x or y is even or pixel is on
meurigp 17:4e6f0f7f22fb 167
meurigp 17:4e6f0f7f22fb 168 randomX = rand() % 83 + 1; // randomX in the range 1 to 83
meurigp 17:4e6f0f7f22fb 169 randomY = rand() % 47 + 1; // randomY in the range 1 to 47
meurigp 17:4e6f0f7f22fb 170 randomXoddEven = randomX%2; // find out whether odd or even
meurigp 17:4e6f0f7f22fb 171 randomYoddEven = randomY%2;
meurigp 17:4e6f0f7f22fb 172 }
meurigp 17:4e6f0f7f22fb 173
meurigp 17:4e6f0f7f22fb 174 lcd.drawRect(randomX,randomY,1,1,1);
meurigp 17:4e6f0f7f22fb 175 }
meurigp 1:97ac723959f2 176
meurigp 1:97ac723959f2 177 }
meurigp 3:0e3179c452c5 178
meurigp 5:257b4816ac6a 179 void newFruitXY() // new fruit coordinate values are given before it is passed to the generateFood function
meurigp 3:0e3179c452c5 180 {
meurigp 4:3ceebacef5f1 181
meurigp 3:0e3179c452c5 182 randomX = rand() % 83 + 1; // randomX in the range 1 to 81
meurigp 3:0e3179c452c5 183 randomY = rand() % 47 + 1; // randomY in the range 1 to 47
meurigp 3:0e3179c452c5 184 randomXoddEven = randomX%2; // find out whether odd or even
meurigp 3:0e3179c452c5 185 randomYoddEven = randomY%2;
meurigp 1:97ac723959f2 186
meurigp 3:0e3179c452c5 187 }
meurigp 4:3ceebacef5f1 188
meurigp 4:3ceebacef5f1 189 void moveSnake() {
meurigp 4:3ceebacef5f1 190
meurigp 4:3ceebacef5f1 191 if (joystick.direction == LEFT) {
meurigp 4:3ceebacef5f1 192 if (currentDirection != right) { // change the currentDirection according to joystick input, providing
meurigp 4:3ceebacef5f1 193 currentDirection = left; // it's not the opposite direction to the current direction
meurigp 4:3ceebacef5f1 194 }
meurigp 4:3ceebacef5f1 195 }
meurigp 4:3ceebacef5f1 196 else if (joystick.direction == RIGHT) {
meurigp 4:3ceebacef5f1 197 if (currentDirection != left) { // change the currentDirection according to joystick input, providing
meurigp 4:3ceebacef5f1 198 currentDirection = right; // it's not the opposite direction to the current direction
meurigp 4:3ceebacef5f1 199 }
meurigp 4:3ceebacef5f1 200 }
meurigp 4:3ceebacef5f1 201 else if (joystick.direction == UP) {
meurigp 4:3ceebacef5f1 202 if (currentDirection != down) { // change the currentDirection according to joystick input, providing
meurigp 4:3ceebacef5f1 203 currentDirection = up; // it's not the opposite direction to the current direction
meurigp 4:3ceebacef5f1 204 }
meurigp 4:3ceebacef5f1 205 }
meurigp 4:3ceebacef5f1 206 else if (joystick.direction == DOWN) {
meurigp 4:3ceebacef5f1 207 if (currentDirection != up) { // change the currentDirection according to joystick input, providing
meurigp 4:3ceebacef5f1 208 currentDirection = down; // it's not the opposite direction to the current direction
meurigp 4:3ceebacef5f1 209 }
meurigp 4:3ceebacef5f1 210 }
meurigp 13:08159ea3d556 211 }
meurigp 13:08159ea3d556 212
meurigp 13:08159ea3d556 213 void gameLogic() {
meurigp 13:08159ea3d556 214
meurigp 13:08159ea3d556 215 lcd.clear();
meurigp 13:08159ea3d556 216 greenLed = 1;
meurigp 15:a5590211888c 217
meurigp 13:08159ea3d556 218
meurigp 13:08159ea3d556 219 prev_i = snakeTailX[0];
meurigp 13:08159ea3d556 220 prev_j = snakeTailY[0];
meurigp 13:08159ea3d556 221 snakeTailX[0] = i;
meurigp 13:08159ea3d556 222 snakeTailY[0] = j;
meurigp 8:9b767dd1e549 223
meurigp 15:a5590211888c 224 for (int a=1; a<snakeTailLength; a++) { // loops through snakeTail array and assigns previous seg's coordinates to current one
meurigp 13:08159ea3d556 225 prev2_i = snakeTailX[a];
meurigp 13:08159ea3d556 226 prev2_j = snakeTailY[a];
meurigp 13:08159ea3d556 227 snakeTailX[a] = prev_i;
meurigp 13:08159ea3d556 228 snakeTailY[a] = prev_j;
meurigp 13:08159ea3d556 229 prev_i = prev2_i;
meurigp 13:08159ea3d556 230 prev_j = prev2_j;
meurigp 13:08159ea3d556 231 }
meurigp 13:08159ea3d556 232
meurigp 13:08159ea3d556 233
meurigp 13:08159ea3d556 234 if (currentDirection == left) { // shift snake head coordinates according to current direction
meurigp 13:08159ea3d556 235 i -= 2; } // move left
meurigp 13:08159ea3d556 236 else if (currentDirection == right) {
meurigp 13:08159ea3d556 237 i += 2; } // move right
meurigp 13:08159ea3d556 238 else if (currentDirection == up) {
meurigp 13:08159ea3d556 239 j -= 2; } // move up
meurigp 13:08159ea3d556 240 else if (currentDirection == down) {
meurigp 13:08159ea3d556 241 j += 2; } // move down
meurigp 13:08159ea3d556 242
meurigp 13:08159ea3d556 243
meurigp 13:08159ea3d556 244 lcd.drawRect(i,j,1,1,1); // snake head
meurigp 13:08159ea3d556 245 for (int b=0; b<snakeTailLength; b++) {
meurigp 13:08159ea3d556 246 lcd.drawRect(snakeTailX[b],snakeTailY[b],1,1,1);
meurigp 13:08159ea3d556 247 }
meurigp 13:08159ea3d556 248
meurigp 13:08159ea3d556 249 lcd.refresh();
meurigp 12:825a402d230f 250
meurigp 13:08159ea3d556 251 lcd.drawRect(randomX,randomY,1,1,1); // food
meurigp 18:67d5ae64fbd1 252
meurigp 18:67d5ae64fbd1 253 if (gameType == classicMode) { // map types
meurigp 17:4e6f0f7f22fb 254 hardWall();
meurigp 17:4e6f0f7f22fb 255 }
meurigp 17:4e6f0f7f22fb 256 else if (gameType == infiniteMode) {
meurigp 17:4e6f0f7f22fb 257 wrapAround();
meurigp 17:4e6f0f7f22fb 258 }
meurigp 17:4e6f0f7f22fb 259 else {
meurigp 17:4e6f0f7f22fb 260 specialMap();
meurigp 17:4e6f0f7f22fb 261 }
meurigp 13:08159ea3d556 262
meurigp 13:08159ea3d556 263 if (i == randomX && j == randomY) { // if fruit is eaten
meurigp 13:08159ea3d556 264 greenLed = 0;
meurigp 15:a5590211888c 265 buzzer.beep(2000,0.2);
meurigp 13:08159ea3d556 266 scoreCalculation();
meurigp 13:08159ea3d556 267 snakeTailLength++;
meurigp 13:08159ea3d556 268 newFruitXY();
meurigp 13:08159ea3d556 269 generateFood();
meurigp 13:08159ea3d556 270 }
meurigp 15:a5590211888c 271
meurigp 15:a5590211888c 272 if (snakeTailLength > 4) { // if snake eats itself
meurigp 15:a5590211888c 273 for (int q=1; q<snakeTailLength; q++) {
meurigp 15:a5590211888c 274 if (snakeTailX[q] == i && snakeTailY[q] == j) {
meurigp 15:a5590211888c 275 gameOver();
meurigp 15:a5590211888c 276 }
meurigp 15:a5590211888c 277 }
meurigp 15:a5590211888c 278 }
meurigp 14:56e355c5cfc9 279
meurigp 13:08159ea3d556 280 }
meurigp 12:825a402d230f 281
meurigp 10:7820b46476ea 282
meurigp 5:257b4816ac6a 283 void hardWall() {
meurigp 5:257b4816ac6a 284
meurigp 5:257b4816ac6a 285 lcd.drawRect(0,0,83,47,0);
meurigp 6:9a5706a27240 286 lcd.refresh();
meurigp 6:9a5706a27240 287 if (i == 0 || i+1 == 0 ||
meurigp 6:9a5706a27240 288 i == 83 || i+1 == 83 || // if any of the 4 pixels within the snake head touch the border
meurigp 6:9a5706a27240 289 j == 0 || j+1 == 0 ||
meurigp 9:6d7074258c63 290 j == 47 || j+1 == 47)
meurigp 9:6d7074258c63 291 {
meurigp 20:f634b1060981 292 i = 41;
meurigp 20:f634b1060981 293 j = 23;
meurigp 9:6d7074258c63 294 gameOver();
meurigp 6:9a5706a27240 295 }
meurigp 5:257b4816ac6a 296
meurigp 5:257b4816ac6a 297 }
meurigp 5:257b4816ac6a 298
meurigp 9:6d7074258c63 299 void gameOver() {
meurigp 9:6d7074258c63 300
meurigp 9:6d7074258c63 301 redLed = 1;
meurigp 9:6d7074258c63 302 if(score > top_score) {
meurigp 9:6d7074258c63 303 ////////////////////// Simple writing example //////////////////////////
meurigp 9:6d7074258c63 304
meurigp 9:6d7074258c63 305 // open file for writing ('w') - creates file if it doesn't exist and overwrites
meurigp 9:6d7074258c63 306 // if it does. If you wish to add a score onto a list, then you can
meurigp 9:6d7074258c63 307 // append instead 'a'. This will open the file if it exists and start
meurigp 9:6d7074258c63 308 // writing at the end. It will create the file if it doesn't exist.
meurigp 9:6d7074258c63 309 fp = fopen("/sd/topscore.txt", "w");
meurigp 9:6d7074258c63 310 int top_score = score;
meurigp 9:6d7074258c63 311
meurigp 9:6d7074258c63 312 if (fp == NULL) { // if it can't open the file then print error message
meurigp 9:6d7074258c63 313 serial.printf("Error! Unable to open file!\n");
meurigp 9:6d7074258c63 314 } else { // opened file so can write
meurigp 9:6d7074258c63 315 serial.printf("Writing to file....");
meurigp 9:6d7074258c63 316 fprintf(fp, "%d",top_score); // ensure data type matches
meurigp 9:6d7074258c63 317 serial.printf("Done.\n");
meurigp 9:6d7074258c63 318 fclose(fp); // ensure you close the file after writing
meurigp 9:6d7074258c63 319 }
meurigp 9:6d7074258c63 320 }
meurigp 9:6d7074258c63 321 gamePlaying = false;
meurigp 9:6d7074258c63 322 lcd.clear();
meurigp 15:a5590211888c 323 buzzer.beep(294,0.5);
meurigp 9:6d7074258c63 324 wait(0.5);
meurigp 9:6d7074258c63 325 lcd.printString("Game Over",15,0); // width(6) * n(9) = 54, 84-54 = 30, 30/2 = 15
meurigp 15:a5590211888c 326 buzzer.beep(277,0.5);
meurigp 9:6d7074258c63 327 wait(0.5);
meurigp 9:6d7074258c63 328
meurigp 9:6d7074258c63 329 char buffer[14];
meurigp 9:6d7074258c63 330 int length = sprintf(buffer,"Score:%i",score); // display score of round
meurigp 9:6d7074258c63 331 if (length <= 14) { // if string will fit on display
meurigp 9:6d7074258c63 332 lcd.printString(buffer,0,1); } // display on screen
meurigp 15:a5590211888c 333 buzzer.beep(262,2);
meurigp 18:67d5ae64fbd1 334 wait(0.5);
meurigp 9:6d7074258c63 335 ////////////////////// Simple reading example //////////////////////////
meurigp 9:6d7074258c63 336
meurigp 9:6d7074258c63 337 // now open file for reading
meurigp 9:6d7074258c63 338 fp = fopen("/sd/topscore.txt", "r");
meurigp 9:6d7074258c63 339 // int stored_top_score = -1; // -1 to demonstrate it has changed after reading
meurigp 9:6d7074258c63 340
meurigp 9:6d7074258c63 341 if (fp == NULL) { // if it can't open the file then print error message
meurigp 9:6d7074258c63 342 serial.printf("Error! Unable to open file!\n");
meurigp 9:6d7074258c63 343 } else { // opened file so can write
meurigp 9:6d7074258c63 344 fscanf(fp, "%d",&top_score); // ensure data type matches - note address operator (&)
meurigp 9:6d7074258c63 345 serial.printf("Read %d from file.\n",top_score);
meurigp 9:6d7074258c63 346 char buffer[14];
meurigp 9:6d7074258c63 347 int length = sprintf(buffer,"HI Score:%i",top_score); // display score of round
meurigp 9:6d7074258c63 348 if (length <= 14) { // if string will fit on display
meurigp 9:6d7074258c63 349 lcd.printString(buffer,0,2); } // display on screen
meurigp 9:6d7074258c63 350 fclose(fp); // ensure you close the file after reading
meurigp 9:6d7074258c63 351 }
meurigp 9:6d7074258c63 352 wait(0.5);
meurigp 9:6d7074258c63 353 redLed = 0;
meurigp 9:6d7074258c63 354
meurigp 9:6d7074258c63 355 lcd.printString("RB - Restart",0,4);
meurigp 9:6d7074258c63 356 wait(0.5);
meurigp 9:6d7074258c63 357 lcd.printString("LB - Menu",0,5);
meurigp 18:67d5ae64fbd1 358
meurigp 18:67d5ae64fbd1 359 while(1) {
meurigp 18:67d5ae64fbd1 360 if (rb_flag == 1) {
meurigp 18:67d5ae64fbd1 361 rb_flag = 0;
meurigp 18:67d5ae64fbd1 362 gamePlaying = true;
meurigp 18:67d5ae64fbd1 363 mainGame();
meurigp 18:67d5ae64fbd1 364 }
meurigp 20:f634b1060981 365 rb_flag = 0;
meurigp 18:67d5ae64fbd1 366 if (lb_flag == 1) {
meurigp 18:67d5ae64fbd1 367 lb_flag = 0;
meurigp 19:8907a82ebe09 368 gamePlaying = false;
meurigp 19:8907a82ebe09 369 mainMenu();
meurigp 20:f634b1060981 370 }
meurigp 18:67d5ae64fbd1 371 sleep();
meurigp 18:67d5ae64fbd1 372 }
meurigp 9:6d7074258c63 373 }
meurigp 9:6d7074258c63 374
meurigp 9:6d7074258c63 375
meurigp 6:9a5706a27240 376 void specialMap() {
meurigp 6:9a5706a27240 377
meurigp 18:67d5ae64fbd1 378 lcd.drawRect(0,0,83,47,0);
meurigp 20:f634b1060981 379 lcd.drawRect(15,9,1,31,1);
meurigp 20:f634b1060981 380 lcd.drawRect(33,9,1,31,1);
meurigp 20:f634b1060981 381 lcd.drawRect(49,9,1,31,1);
meurigp 18:67d5ae64fbd1 382 lcd.refresh();
meurigp 18:67d5ae64fbd1 383 if (i == 0 || i+1 == 0 ||
meurigp 18:67d5ae64fbd1 384 i == 83 || i+1 == 83 || // if any of the 4 pixels within the snake head touch the border
meurigp 18:67d5ae64fbd1 385 j == 0 || j+1 == 0 ||
meurigp 18:67d5ae64fbd1 386 j == 47 || j+1 == 47)
meurigp 18:67d5ae64fbd1 387 {
meurigp 20:f634b1060981 388 i = 13;
meurigp 20:f634b1060981 389 j = 5;
meurigp 18:67d5ae64fbd1 390 gameOver();
meurigp 6:9a5706a27240 391 }
meurigp 6:9a5706a27240 392
meurigp 6:9a5706a27240 393 }
meurigp 6:9a5706a27240 394
meurigp 12:825a402d230f 395 void wrapAround() {
meurigp 6:9a5706a27240 396
meurigp 14:56e355c5cfc9 397 if (i == -2) {
meurigp 14:56e355c5cfc9 398 i = 82;
meurigp 6:9a5706a27240 399 }
meurigp 6:9a5706a27240 400 if (i == 84) {
meurigp 6:9a5706a27240 401 i = 0;
meurigp 6:9a5706a27240 402 }
meurigp 14:56e355c5cfc9 403 if (j == -2) {
meurigp 14:56e355c5cfc9 404 j = 46;
meurigp 6:9a5706a27240 405 }
meurigp 14:56e355c5cfc9 406 if (j == 48) {
meurigp 14:56e355c5cfc9 407 j = 0;
meurigp 14:56e355c5cfc9 408 }
meurigp 6:9a5706a27240 409
meurigp 12:825a402d230f 410 }
meurigp 6:9a5706a27240 411
meurigp 6:9a5706a27240 412
meurigp 5:257b4816ac6a 413 void scoreCalculation() {
meurigp 5:257b4816ac6a 414
meurigp 5:257b4816ac6a 415 score += fruitValue; // each time fruit is eaten score is calculated and fruit value will increase by 1
meurigp 5:257b4816ac6a 416
meurigp 5:257b4816ac6a 417 fruitValue++;
meurigp 5:257b4816ac6a 418
meurigp 8:9b767dd1e549 419 //serial.printf("score = %i\n",score);
meurigp 8:9b767dd1e549 420 //serial.printf("fruitValue = %i\n\n",fruitValue);
meurigp 5:257b4816ac6a 421
meurigp 8:9b767dd1e549 422 }
meurigp 8:9b767dd1e549 423
meurigp 8:9b767dd1e549 424 void initSnakeTail() {
meurigp 8:9b767dd1e549 425
meurigp 17:4e6f0f7f22fb 426 if (gameType == classicMode) {
meurigp 8:9b767dd1e549 427 prev_i = 39;
meurigp 8:9b767dd1e549 428 prev_j = 23;
meurigp 17:4e6f0f7f22fb 429 prev2_i = 37;
meurigp 17:4e6f0f7f22fb 430 prev2_j = 23;
meurigp 17:4e6f0f7f22fb 431 }
meurigp 17:4e6f0f7f22fb 432 else if (gameType == infiniteMode) {
meurigp 17:4e6f0f7f22fb 433 prev_i = 38;
meurigp 17:4e6f0f7f22fb 434 prev_j = 22;
meurigp 17:4e6f0f7f22fb 435 prev2_i = 36;
meurigp 17:4e6f0f7f22fb 436 prev2_j = 22;
meurigp 17:4e6f0f7f22fb 437 }
meurigp 17:4e6f0f7f22fb 438 else {
meurigp 17:4e6f0f7f22fb 439 prev_i = 11;
meurigp 17:4e6f0f7f22fb 440 prev_j = 5;
meurigp 17:4e6f0f7f22fb 441 prev2_i = 9;
meurigp 17:4e6f0f7f22fb 442 prev2_j = 5;
meurigp 17:4e6f0f7f22fb 443 }
meurigp 17:4e6f0f7f22fb 444
meurigp 20:f634b1060981 445 snakeTailX[0] = i;
meurigp 20:f634b1060981 446 snakeTailY[0] = j;
meurigp 8:9b767dd1e549 447 snakeTailX[1] = prev_i;
meurigp 8:9b767dd1e549 448 snakeTailY[1] = prev_j;
meurigp 8:9b767dd1e549 449 snakeTailX[2] = prev2_i;
meurigp 8:9b767dd1e549 450 snakeTailY[2] = prev2_j;
meurigp 8:9b767dd1e549 451
meurigp 8:9b767dd1e549 452 lcd.drawRect(i,j,1,1,1); // snake head
meurigp 8:9b767dd1e549 453 for (int b=0; b<snakeTailLength; b++) {
meurigp 9:6d7074258c63 454 lcd.drawRect(snakeTailX[b],snakeTailY[b],1,1,1);
meurigp 9:6d7074258c63 455 }
meurigp 9:6d7074258c63 456 currentDirection = right;
meurigp 8:9b767dd1e549 457
meurigp 9:6d7074258c63 458 }
meurigp 9:6d7074258c63 459
meurigp 9:6d7074258c63 460 void snakeIntro() {
meurigp 9:6d7074258c63 461
meurigp 9:6d7074258c63 462 for(int i=0; i<WIDTH; i++) {
meurigp 9:6d7074258c63 463 for(int j=0; j<HEIGHT; j++) {
meurigp 9:6d7074258c63 464 lcd.setPixel(i,j);
meurigp 9:6d7074258c63 465 }
meurigp 9:6d7074258c63 466 }
meurigp 9:6d7074258c63 467 for (int q=0; q<WIDTH/2; q++) {
meurigp 9:6d7074258c63 468 lcd.drawCircle(WIDTH/2,HEIGHT/2,q,2);
meurigp 9:6d7074258c63 469 wait_ms(2);
meurigp 9:6d7074258c63 470 } // x,y,radius,white fill
meurigp 9:6d7074258c63 471
meurigp 9:6d7074258c63 472 lcd.printString("Snake",27,0);
meurigp 15:a5590211888c 473 buzzer.beep(2000,0.5);
meurigp 9:6d7074258c63 474 wait(0.5);
meurigp 9:6d7074258c63 475 lcd.printString("by",36,2);
meurigp 15:a5590211888c 476 buzzer.beep(1000,0.5);
meurigp 9:6d7074258c63 477 wait(0.5);
meurigp 9:6d7074258c63 478 lcd.printString("Meurig",24,3);
meurigp 15:a5590211888c 479 buzzer.beep(500,0.5);
meurigp 9:6d7074258c63 480 wait(0.5);
meurigp 9:6d7074258c63 481 lcd.printString("Phillips",18,4);
meurigp 15:a5590211888c 482 buzzer.beep(250,2);
meurigp 9:6d7074258c63 483 wait(2);
meurigp 9:6d7074258c63 484
meurigp 9:6d7074258c63 485 lcd.clear();
meurigp 9:6d7074258c63 486
meurigp 12:825a402d230f 487 }
meurigp 12:825a402d230f 488
meurigp 12:825a402d230f 489 void gamePaused() {
meurigp 12:825a402d230f 490
meurigp 14:56e355c5cfc9 491 wait_ms(100);
meurigp 12:825a402d230f 492 pauseCount++;
meurigp 12:825a402d230f 493 lcd.clear();
meurigp 12:825a402d230f 494 char buffer[14];
meurigp 12:825a402d230f 495 int length = sprintf(buffer,"%i left",3-pauseCount); // number of pauses left
meurigp 12:825a402d230f 496 if (length <= 14) { // if string will fit on display
meurigp 14:56e355c5cfc9 497 lcd.printString(buffer,24,3); } // display on screen
meurigp 14:56e355c5cfc9 498
meurigp 14:56e355c5cfc9 499 lcd.printString("Paused 5",18,1);
meurigp 14:56e355c5cfc9 500 wait(1);
meurigp 14:56e355c5cfc9 501 lcd.printString("Paused 4",18,1);
meurigp 14:56e355c5cfc9 502 wait(1);
meurigp 14:56e355c5cfc9 503 lcd.printString("Paused 3",18,1);
meurigp 14:56e355c5cfc9 504 wait(1);
meurigp 14:56e355c5cfc9 505 lcd.printString("Paused 2",18,1);
meurigp 14:56e355c5cfc9 506 wait(1);
meurigp 14:56e355c5cfc9 507 lcd.printString("Paused 1",18,1);
meurigp 14:56e355c5cfc9 508 wait(1);
meurigp 14:56e355c5cfc9 509
meurigp 14:56e355c5cfc9 510 }
meurigp 14:56e355c5cfc9 511
meurigp 14:56e355c5cfc9 512 void timer_isr()
meurigp 14:56e355c5cfc9 513 {
meurigp 14:56e355c5cfc9 514 game_timer_flag = 1;
meurigp 16:68b9460d4c76 515 }
meurigp 16:68b9460d4c76 516
meurigp 16:68b9460d4c76 517 void rb_isr()
meurigp 16:68b9460d4c76 518 {
meurigp 16:68b9460d4c76 519 rb_flag = 1;
meurigp 16:68b9460d4c76 520 }
meurigp 16:68b9460d4c76 521
meurigp 16:68b9460d4c76 522 void lb_isr()
meurigp 16:68b9460d4c76 523 {
meurigp 16:68b9460d4c76 524 lb_flag = 1;
meurigp 12:825a402d230f 525 }