ELEC2645 (2015/16) / Mbed 2 deprecated SnakeProjectRev1

Dependencies:   Joystick N5110 SDFileSystem beep fsmMenu mbed

Fork of SnakeProjectRev1 by Meurig Phillips

Committer:
meurigp
Date:
Wed May 04 18:27:39 2016 +0000
Revision:
18:67d5ae64fbd1
Parent:
17:4e6f0f7f22fb
Child:
19:8907a82ebe09
restart interrupt working for infinite but not classic

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