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: Joystick N5110 SDFileSystem beep fsmMenu mbed
Fork of SnakeProjectRev1 by
main.cpp
- Committer:
- meurigp
- Date:
- 2016-05-01
- Revision:
- 11:f8478bc749e0
- Parent:
- 10:7820b46476ea
- Child:
- 12:825a402d230f
File content as of revision 11:f8478bc749e0:
#include "mbed.h" #include "main.h" #include "N5110.h" #include "beep.h" #include "SDFileSystem.h" #include "Joystick.h" // VCC, SCE, RST, D/C, MOSI, SCLK, LED N5110 lcd (PTD3, PTA0 , PTC4 , PTD0 , PTD2 , PTD1 , PTC3); // Can also power (VCC) directly from VOUT (3.3 V) - // Can give better performance due to current limitation from GPIO pin // Connections to SD card holder on K64F (SPI interface) SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd"); // MOSI, MISO, SCK, CS //DigitalOut greenLed(PTC2); //DigitalOut redLed(PTA2); //Beep buzzer(PTA1); /* // timer to regularly read the joystick Ticker pollJoystick; // Serial for debug Serial serial(USBTX,USBRX); Ticker gameTicker; /// create enumerated type (0,1,2,3 etc. for current direction snake is travelling (not joystick reading)) enum CurrentDirection { up, down, left, right, centre, }; CurrentDirection currentDirection = centre; /// intialise direction at beginning int randomX = rand() % 83 + 1; // randomX in the range 1 to 81 int randomY = rand() % 47 + 1; // randomY in the range 1 to 47 int randomXoddEven = randomX%2; // find out whether odd or even int randomYoddEven = randomY%2; int snakeTailX[100]; int snakeTailY[100]; int snakeTailLength = 3; int score = 0; int top_score = 0; int fruitValue = 10; int i = 41; // snake head origin x int j = 23; // snake head origin y int prev_i; int prev_j; int prev2_i; int prev2_j; bool gamePlaying = false; // function prototypes void generateFood(); void newFruitXY(); void moveSnake(); void hardWall(); void specialMap(); void wrapAround(); void scoreCalculation(); void gameOver(); void initSnakeTail(); void snakeIntro(); */ FILE *fp; // this is our file pointer int main() { wait(1); calibrateJoystick(); // get centred values of joystick pollJoystick.attach(&updateJoystick,0.5/10.0); // read joystick 20 times per second srand(time(NULL)); greenLed = 1; redLed = 0; lcd.init(); //snakeIntro(); hardWall(); generateFood(); gamePlaying = true; initSnakeTail(); while(1) { if (printFlag) { // if flag set, clear flag and print joystick values to serial port printFlag = 0; if (gamePlaying == true) { moveSnake(); } else if (gamePlaying == false) { } } sleep(); // put the MCU to sleep until an interrupt wakes it up } } void generateFood() { while (randomXoddEven ==0 || randomYoddEven ==0 || lcd.getPixel(randomX,randomY) >= 1) { // do while x or y is even or pixel is on randomX = rand() % 83 + 1; // randomX in the range 1 to 83 randomY = rand() % 47 + 1; // randomY in the range 1 to 47 // serial.printf("X = %i\n",randomX); // debug // serial.printf("Y = %i\n\n",randomY); randomXoddEven = randomX%2; // find out whether odd or even randomYoddEven = randomY%2; } lcd.drawRect(randomX,randomY,1,1,1); } void newFruitXY() // new fruit coordinate values are given before it is passed to the generateFood function { randomX = rand() % 83 + 1; // randomX in the range 1 to 81 randomY = rand() % 47 + 1; // randomY in the range 1 to 47 randomXoddEven = randomX%2; // find out whether odd or even randomYoddEven = randomY%2; } void moveSnake() { if (joystick.direction == LEFT) { if (currentDirection != right) { // change the currentDirection according to joystick input, providing currentDirection = left; // it's not the opposite direction to the current direction } } else if (joystick.direction == RIGHT) { if (currentDirection != left) { // change the currentDirection according to joystick input, providing currentDirection = right; // it's not the opposite direction to the current direction } } else if (joystick.direction == UP) { if (currentDirection != down) { // change the currentDirection according to joystick input, providing currentDirection = up; // it's not the opposite direction to the current direction } } else if (joystick.direction == DOWN) { if (currentDirection != up) { // change the currentDirection according to joystick input, providing currentDirection = down; // it's not the opposite direction to the current direction } } lcd.clear(); greenLed = 1; if (snakeTailLength > 4) { for (int q=1; q<snakeTailLength; q++) { if (snakeTailX[q] == i && snakeTailY[q] == j) { gameOver(); } } } if (gamePlaying == true) { prev_i = snakeTailX[0]; prev_j = snakeTailY[0]; snakeTailX[0] = i; snakeTailY[0] = j; for (int a=1; a<snakeTailLength; a++) { prev2_i = snakeTailX[a]; prev2_j = snakeTailY[a]; snakeTailX[a] = prev_i; snakeTailY[a] = prev_j; prev_i = prev2_i; prev_j = prev2_j; } if (currentDirection == left) { // shift snake head coordinates according to current direction i -= 2; } // move left else if (currentDirection == right) { i += 2; } // move right else if (currentDirection == up) { j -= 2; } // move up else if (currentDirection == down) { j += 2; } // move down lcd.drawRect(i,j,1,1,1); // snake head for (int b=0; b<snakeTailLength; b++) { lcd.drawRect(snakeTailX[b],snakeTailY[b],1,1,1); } lcd.refresh(); lcd.drawRect(randomX,randomY,1,1,1); // food hardWall(); //specialMap(); //wrapAround(); if (i == randomX && j == randomY) { // if fruit is eaten greenLed = 0; //buzzer.beep(2000,0.2); scoreCalculation(); snakeTailLength++; newFruitXY(); generateFood(); } wait(0.1); } } void hardWall() { lcd.drawRect(0,0,83,47,0); lcd.refresh(); if (i == 0 || i+1 == 0 || i == 83 || i+1 == 83 || // if any of the 4 pixels within the snake head touch the border j == 0 || j+1 == 0 || j == 47 || j+1 == 47) { gameOver(); } } void gameOver() { redLed = 1; if(score > top_score) { ////////////////////// Simple writing example ////////////////////////// // open file for writing ('w') - creates file if it doesn't exist and overwrites // if it does. If you wish to add a score onto a list, then you can // append instead 'a'. This will open the file if it exists and start // writing at the end. It will create the file if it doesn't exist. fp = fopen("/sd/topscore.txt", "w"); int top_score = score; if (fp == NULL) { // if it can't open the file then print error message serial.printf("Error! Unable to open file!\n"); } else { // opened file so can write serial.printf("Writing to file...."); fprintf(fp, "%d",top_score); // ensure data type matches serial.printf("Done.\n"); fclose(fp); // ensure you close the file after writing } } gamePlaying = false; lcd.clear(); //buzzer.beep(294,0.5); wait(0.5); lcd.printString("Game Over",15,0); // width(6) * n(9) = 54, 84-54 = 30, 30/2 = 15 //buzzer.beep(277,0.5); wait(0.5); char buffer[14]; int length = sprintf(buffer,"Score:%i",score); // display score of round if (length <= 14) { // if string will fit on display lcd.printString(buffer,0,1); } // display on screen //buzzer.beep(262,2); ////////////////////// Simple reading example ////////////////////////// // now open file for reading fp = fopen("/sd/topscore.txt", "r"); // int stored_top_score = -1; // -1 to demonstrate it has changed after reading if (fp == NULL) { // if it can't open the file then print error message serial.printf("Error! Unable to open file!\n"); } else { // opened file so can write fscanf(fp, "%d",&top_score); // ensure data type matches - note address operator (&) serial.printf("Read %d from file.\n",top_score); char buffer[14]; int length = sprintf(buffer,"HI Score:%i",top_score); // display score of round if (length <= 14) { // if string will fit on display lcd.printString(buffer,0,2); } // display on screen fclose(fp); // ensure you close the file after reading } wait(0.5); redLed = 0; lcd.printString("RB - Restart",0,4); wait(0.5); lcd.printString("LB - Menu",0,5); /* if (RB == 0) { moveSnake(); } */ } void specialMap() { for (int i=0; i<21; i++) { // top/bottom left x line lcd.setPixel(i,0); lcd.setPixel(i,47); lcd.refresh(); } for (int i=63; i<84; i++) { // top/bottom right x line lcd.setPixel(i,0); lcd.setPixel(i,47); lcd.refresh(); } for (int i=37; i<47; i++) { // top/bottom middle x line lcd.setPixel(i,0); lcd.setPixel(i,47); lcd.refresh(); } for (int j=0; j<17; j++) { // left/right top y line lcd.setPixel(0,j); lcd.setPixel(83,j); lcd.refresh(); } for (int j=29; j<48; j++) { // left/right bottom y line lcd.setPixel(0,j); lcd.setPixel(83,j); lcd.refresh(); } for (int i=41; i<43; i++) { // vertical cross line for (int j=14; j<34; j++) { lcd.setPixel(i,j); lcd.refresh(); } } for (int i=32; i<52; i++) { // horizontal cross line for (int j=23; j<25; j++) { lcd.setPixel(i,j); lcd.refresh(); } } } /*void wrapAround() { if (i == -1) { i = 83; } if (i == 84) { i = 0; } if (j == -1) { j = 47; } if (j+1 == 48) { j+1 = 0; } lcd.setPixel(i,j); lcd.setPixel(i,j+1); lcd.setPixel(i+1,j+1); lcd.setPixel(i+1,j); lcd.setPixel(prev_i,prev_j); lcd.setPixel(prev_i,prev_j+1); lcd.setPixel(prev_i+1,prev_j+1); lcd.setPixel(prev_i+1,prev_j); lcd.setPixel(prev2_i,prev2_j); lcd.setPixel(prev2_i,prev2_j+1); lcd.setPixel(prev2_i+1,prev2_j+1); lcd.setPixel(prev2_i+1,prev2_j); lcd.refresh(); } */ void scoreCalculation() { score += fruitValue; // each time fruit is eaten score is calculated and fruit value will increase by 1 fruitValue++; //serial.printf("score = %i\n",score); //serial.printf("fruitValue = %i\n\n",fruitValue); } void initSnakeTail() { prev_i = 39; prev_j = 23; snakeTailX[1] = prev_i; snakeTailY[1] = prev_j; prev2_i = 37; prev2_j = 23; snakeTailX[2] = prev2_i; snakeTailY[2] = prev2_j; lcd.drawRect(i,j,1,1,1); // snake head for (int b=0; b<snakeTailLength; b++) { lcd.drawRect(snakeTailX[b],snakeTailY[b],1,1,1); } currentDirection = right; } void snakeIntro() { for(int i=0; i<WIDTH; i++) { for(int j=0; j<HEIGHT; j++) { lcd.setPixel(i,j); } } for (int q=0; q<WIDTH/2; q++) { lcd.drawCircle(WIDTH/2,HEIGHT/2,q,2); wait_ms(2); } // x,y,radius,white fill lcd.printString("Snake",27,0); //buzzer.beep(2000,0.5); wait(0.5); lcd.printString("by",36,2); //buzzer.beep(1000,0.5); wait(0.5); lcd.printString("Meurig",24,3); //buzzer.beep(500,0.5); wait(0.5); lcd.printString("Phillips",18,4); //buzzer.beep(250,2); wait(2); lcd.clear(); }