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-04-22
- Revision:
- 7:f7f2abab16ef
- Parent:
- 6:9a5706a27240
- Child:
- 8:9b767dd1e549
File content as of revision 7:f7f2abab16ef:
/* Joystick Example code of how to read a joystick https://www.sparkfun.com/products/9032 Craig A. Evans 7 March 2015 */ #include "mbed.h" #include "N5110.h" // change this to alter tolerance of joystick direction #define DIRECTION_TOLERANCE 0.05 // 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 for joystick DigitalIn button(PTB18); AnalogIn xPot(PTB2); AnalogIn yPot(PTB3); //PwmOut greenLed(PTC2); // timer to regularly read the joystick Ticker pollJoystick; // Serial for debug Serial serial(USBTX,USBRX); // create enumerated type (0,1,2,3 etc. for direction) // could be extended for diagonals etc. enum DirectionName { UP, DOWN, LEFT, RIGHT, CENTRE, UNKNOWN }; /// 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 // struct for Joystick typedef struct JoyStick Joystick; struct JoyStick { float x; // current x value float x0; // 'centred' x value float y; // current y value float y0; // 'centred' y value int button; // button state (assume pull-down used, so 1 = pressed, 0 = unpressed) DirectionName direction; // current direction }; // create struct variable Joystick joystick; int printFlag = 0; int pixels[84][48]; 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; int score = 0; int fruitValue = 10; int i = 41; // snake head origin x int j = 23; // snake head origin y int prev_i = 41; int prev_j = 23; int prev2_i = 41; int prev2_j = 23; bool gamePlaying = false; // function prototypes void calibrateJoystick(); void updateJoystick(); void joystickDirection(); void generateFood(); void newFruitXY(); void moveSnake(); void greenLedFlash(); void hardWall(); void specialMap(); void wrapAround(); void scoreCalculation(); int main() { calibrateJoystick(); // get centred values of joystick pollJoystick.attach(&updateJoystick,0.5/10.0); // read joystick 10 times per second srand(time(NULL)); lcd.init(); lcd.drawRect(i,j,1,1,1); // default snake position //hardWall(); generateFood(); gamePlaying = true; // greenLed = 0; 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 calibrateJoystick() // read default positions of the joystick to calibrate later readings { button.mode(PullDown); // must not move during calibration joystick.x0 = xPot; // initial positions in the range 0.0 to 1.0 (0.5 if centred exactly) joystick.y0 = yPot; } void updateJoystick() { // read current joystick values relative to calibrated values (in range -0.5 to 0.5, 0.0 is centred) joystick.x = xPot - joystick.x0; joystick.y = yPot - joystick.y0; // read button state joystick.button = button; // calculate direction depending on x,y values // tolerance allows a little lee-way in case joystick not exactly in the stated direction if ( fabs(joystick.y) < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) { joystick.direction = CENTRE; } else if ( joystick.y > DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) { joystick.direction = UP; } else if ( joystick.y < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) { joystick.direction = DOWN; } else if ( joystick.x > DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) { joystick.direction = LEFT; } else if ( joystick.x < DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) { joystick.direction = RIGHT; } else { joystick.direction = UNKNOWN; } // set flag for printing printFlag = 1; } 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 joystickDirection() { // stcik direction for debug serial.printf("x = %f y = %f button = %d ",joystick.x,joystick.y,joystick.button); // check joystick direction if (joystick.direction == UP) serial.printf(" UP\n"); if (joystick.direction == DOWN) serial.printf(" DOWN\n"); if (joystick.direction == LEFT) serial.printf(" LEFT\n"); if (joystick.direction == RIGHT) serial.printf(" RIGHT\n"); if (joystick.direction == CENTRE) serial.printf(" CENTRE\n"); if (joystick.direction == UNKNOWN) serial.printf(" Unsupported direction\n"); } 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(); prev2_i = prev_i; // previous coordinates of the previous snake head coordinates prev2_j = prev_j; prev_i = i; // previous coordinates of the snake head prev_j = j; if (currentDirection == left) { // shift snake head coordinates according to current direction i -= 2; } else if (currentDirection == right) { i += 2; } else if (currentDirection == up) { j -= 2; } else if (currentDirection == down) { j += 2; } //lcd.drawRect(i,j,1,1,1); // snake head lcd.setPixel(i,j); lcd.setPixel(i,j+1); lcd.setPixel(i+1,j+1); lcd.setPixel(i+1,j); serial.printf("j = %i\n",j); serial.printf("j+1 = %i\n\n",j+1); /* serial.printf("i+1,j+1 = %i,%i\n",i+1,j+1); serial.printf("i+1,j = %i,%i\n",i+1,j); */ //lcd.drawRect(prev_i,prev_j,1,1,1); // seg 1 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); /* serial.printf("prev_i,prev_j = %i,%i\n",prev_i,prev_j); serial.printf("prev_i,prev_j+1 = %i,%i\n",prev_i,prev_j+1); serial.printf("prev_i+1,prev_j+1 = %i,%i\n",prev_i+1,prev_j+1); serial.printf("prev_i+1,prev_j = %i,%i\n",prev_i+1,prev_j); */ //lcd.drawRect(prev2_i,prev2_j,1,1,1); // seg 2 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); /* serial.printf("prev2_i,prev2_j = %i,%i\n",prev2_i,prev2_j); serial.printf("prev2_i,prev2_j+1 = %i,%i\n",prev2_i,prev2_j+1); serial.printf("prev2_i+1,prev2_j+1 = %i,%i\n",prev2_i+1,prev2_j+1); serial.printf("prev2_i+1,prev2_j = %i,%i\n\n",prev2_i+1,prev2_j); */ lcd.refresh(); lcd.drawRect(randomX,randomY,1,1,1); // food hardWall(); //specialMap(); //wrapAround(); if (i == randomX && j == randomY) { // if fruit is eaten //greenLedFlash(); scoreCalculation(); snakeTailLength++; newFruitXY(); generateFood(); } wait(0.5); } /*void greenLedFlash() { for(float p = 1.0f; p > 0.0f; p -= 0.1f) { // green led rapidly decreases from full brightness to off greenLed = p; wait(0.07); } greenLed = 0; } */ 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) { gamePlaying = false; lcd.clear(); lcd.printString("Game Over",15,0); // width(6) * n(9) = 54, 84-54 = 30, 30/2 = 15 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 } } 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); }