ELEC2645 Embedded Systems Project (JOYSTICK)
Dependencies: N5110 SDFileSystem mbed
Diff: main.cpp
- Revision:
- 2:537b8388dc6a
- Parent:
- 1:06958b7bbf65
- Child:
- 4:f17082a43006
diff -r 06958b7bbf65 -r 537b8388dc6a main.cpp --- a/main.cpp Thu May 05 15:03:15 2016 +0000 +++ b/main.cpp Sat May 07 14:35:21 2016 +0000 @@ -1,99 +1,27 @@ -/* -Progress update: -Easter -- Added ticker for joystick update - joystick initial position checker - -week 22 -- main logic behind snake game added - to do : wraparound (optional in main menu) - menu system - play game, settings(joy calibration, wraparound on//off) ; game over screen -*/ - - -#include "mbed.h" -#include "N5110.h" -#include "SDFileSystem.h" -#define JOYSTICK_TOLERANCE 0.1 //direction tolerance of joystick - -// VCC, SCE, RST, D/C, MOSI, SCLK, LED -N5110 lcd (PTE26 , PTA0 , PTC4 , PTD0 , PTD2 , PTD1 , PTC3); -SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd"); - -void init_display(); -void draw_screen(); -void calibrate_joystick(); -void joystick_pos(); -void game_timer_isr(); -void food_pos(); -void snake_move(); -void snake_logic_1(); -float refresh_rate = 10; //refresh screen in Hz -volatile int g_timer_flag = 0; -bool gameOver; //if game has ended -int pdirection; -int gamemode; - -const int width = (84 - 2) / 2 ; // screen width (playable area due to 2x size of snake) -const int height = (48 - 4) / 2 ; // screen height +#include "main.h" -Ticker gameTimer; -Ticker gameTimer1; -Ticker gameTimer2; -Ticker joystickTimer; // ticker timer for joystick poisition update -int fx,fy,Button,score; // global variables to hold data (control) -AnalogIn xAxis(A0); -AnalogIn yAxis(A1); -AnalogIn pot(A2); -DigitalOut red_led(LED_RED); - - - -enum DirectionName { //joystick directions - CENTRE, - UP, - LEFT, - DOWN, - RIGHT, - UNKNOWN -}; - -; -// struct for joystick -typedef struct joystick1 Joystick; -struct joystick1 { - 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 -}; - -Joystick joystick; - -typedef struct snake1 Snake; -struct snake1 { - int hx; // head x value - int hy; // head y value - int length; // snake length - int tailx[100],taily[100]; //tail coordinates array -}; - -Snake snake; - - +int main() +{ + Butt1.rise(butt1_isr); ///initializes the buttons IntterruptIn + Butt1.mode(PullDown); + Butt2.rise(butt2_isr); + Butt2.mode(PullDown); + init_display(); + joystickTimer.attach(joystick_pos,0.1); + calibrate_joystick(); + gamemode = 0; + LED = 0; + level = 2.0; ///default level + levelcalc = 0.4; /// default speed + main_menu(); +} void init_display() { lcd.init(); - lcd.normalMode(); // normal colour mode - lcd.setBrightness(0.5); // put LED backlight on 50% - lcd.clear(); // clear screen (init) -} - -void adjust_brightness() -{ - int x = pot; - lcd.setBrightness(x); + lcd.normalMode(); /// normal colour mode + lcd.setBrightness(0.5); /// put LED backlight on 50% + lcd.clear(); /// clear screen (init) } @@ -101,29 +29,24 @@ { lcd.clear(); - lcd.drawRect(0,1,83,45,0); // borders square + lcd.drawRect(0,1,83,45,0); /// borders square - for (int q = 0; q < snake.length ; q++) { //print snake - //lcd.setPixel (snake.tailx[q],snake.taily[q]); + for (int q = 0; q < snake.length ; q++) { ///print snake + lcd.drawRect ((snake.tailx[q]*2),(snake.taily[q]*2),1,1,1); - // red_led = 0; } - //lcd.setPixel(snake.hx,snake.hy); //print snake head position - lcd.drawRect ((fx * 2), (fy * 2), 1,1,1); - //lcd.setPixel (fx,fy); //print food position - lcd.refresh(); // update display + + lcd.drawRect ((fx * 2), (fy * 2), 1,1,1); /// print food position + + lcd.refresh(); /// update display } -void game_timer_isr() -{ - g_timer_flag = 1; -} void calibrate_joystick() { - //get initial joystick position as offset + ///get initial joystick position as offset joystick.x0 = xAxis; joystick.y0 = yAxis; @@ -151,16 +74,15 @@ } -void snake_move() //move the coordinate of the snake head, if CENTRE, checks for pdirection and repeats. +void snake_move() ///move the coordinate of the snake head, if CENTRE, checks for pdirection and repeats. { - // red_led = 0; - if (pdirection == 0 && joystick.direction == RIGHT) { // disable going backwards + if (pdirection == 0 && ( joystick.direction == RIGHT || joystick.direction == UNKNOWN ) ) { /// disable going backwards snake.hx--; - } else if (pdirection == 1 && joystick.direction == DOWN) { + } else if (pdirection == 1 && ( joystick.direction == DOWN || joystick.direction == UNKNOWN ) ) { snake.hy++; - } else if (pdirection == 2 && joystick.direction == LEFT) { + } else if (pdirection == 2 && ( joystick.direction == LEFT || joystick.direction == UNKNOWN ) ) { snake.hx++; - } else if (pdirection == 3 && joystick.direction == UP) { + } else if (pdirection == 3 && ( joystick.direction == UP || joystick.direction == UNKNOWN ) ) { snake.hy--; } else { @@ -188,6 +110,7 @@ } else if (joystick.direction == DOWN) { snake.hy-- ; pdirection = 3; + } else if (joystick.direction == UNKNOWN) { } else { } @@ -197,170 +120,442 @@ void game() { - //brightnessTimer.attach(adjust_brightness,0.1); + joystickTimer.detach(); gameTimer.detach(); gameTimer1.detach(); gameTimer2.detach(); joystick.direction = CENTRE; - // gamemode = 0; + gamemode = 0; gameOver = false; - snake.hx = width / 2; // initial position of snake head + snake.hx = width / 2; /// initial position of snake head snake.hy = height / 2; food_pos(); score = 0; pdirection = 1; - snake.length = 4; //length including head and tail - for (int w = 0 ; w < snake.length ; w++) { //set initial snake position + snake.length = 4; ///length including head and tail + for (int w = 0 ; w < snake.length ; w++) { ///set initial snake position snake.tailx[w] = (snake.hx - w) ; snake.taily[w] = snake.hy; } - //draw_screen(); - - - if (gamemode == 0) { + joystickTimer.attach(&joystick_pos, 0.1); + gameTimer1.attach(&snake_logic_1, levelcalc); + gameTimer2.attach(&draw_screen, 0.1); + while (!gameOver) { - joystickTimer.attach(&joystick_pos, 0.1); - // gameTimer.attach(&snake_move,0.2); - gameTimer1.attach(&snake_logic_1,0.1); - gameTimer2.attach(&draw_screen, 0.1); + butt2_flag = 0; sleep(); + + if (butt2_flag == 1) { + butt2_flag = 0; + gameTimer1.detach(); + gameTimer2.detach(); + gamePaused_screen(); + } + } if (gameOver == true) { gameTimer1.detach(); gameTimer2.detach(); -} + gameOver_screen(); } } +} - void snake_logic_1() { -//red_led = 0; - snake_move(); - for (int d = (snake.length) ; d > 0 ; d--) { //move all snake body one position back - snake.tailx[d] = snake.tailx[d - 1]; - snake.taily[d] = snake.taily[d - 1]; - - } - snake.tailx[0] = snake.hx; - snake.taily[0] = snake.hy; - // snake.hx = snake.tailx[0]; - // snake.hy = snake.taily[0]; +void snake_logic_1() +{ - // snake_move(); - // draw_screen(); + snake_move(); + for (int d = (snake.length) ; d > 0 ; d--) { ///move all snake body one position back + snake.tailx[d] = snake.tailx[d - 1]; + snake.taily[d] = snake.taily[d - 1]; - for (int p = 1; p < snake.length + 1; p++) { //snake dies when come in contact with tail - if (snake.tailx[0] == snake.tailx[p] && snake.taily[0] == snake.taily[p]) { - gameOver = true; - red_led = 0; - } + } + snake.tailx[0] = snake.hx; + snake.taily[0] = snake.hy; - - - } - - if (snake.tailx[0] == 0 || snake.tailx[0] == width || snake.taily[0] == 1 || snake.taily[0] == height-1) { + for (int p = 1; p < snake.length + 1; p++) { ///snake dies when come in contact with tail + if (snake.tailx[0] == snake.tailx[p] && snake.taily[0] == snake.taily[p]) { gameOver = true; } - if (snake.tailx[0] == fx && snake.taily[0] == fy) { // snake grows when in contact with food - score++; - food_pos(); - snake.length++; - // draw_screen(); + } + + if (snake.tailx[0] == 0 || + snake.tailx[0] == width || + snake.taily[0] == 1 || + snake.taily[0] == height) { /// snake dies when hit wall + gameOver = true; + } + + + if (snake.tailx[0] == fx && snake.taily[0] == fy) { // snake grows when in contact with food + score++; + food_pos(); + snake.length++; + } +} + + +void food_pos() +{ + srand(time(NULL)); + fx = rand() % (width - 3) + 2; // random x from 4 to width - 3 for x coordinate + fy = rand() % (height - 3) + 2; // random y from 4 to height - 3 for y coordinate + +} + +void main_menu() +{ + lcd.clear(); + joystickTimer.detach(); + gameTimer1.detach(); + gameTimer2.detach(); + joystickTimer.attach(joystick_pos,0.15); + butt1_flag = 0; + int select = 0; + while (1) { + switch(select) { + case 0: + switch(joystick.direction) { + case UP: + select = 1; + break; + case DOWN: + select = 2; + break; + } + break; + case 1: + switch(joystick.direction) { + case UP: + select = 2; + break; + case DOWN: + select = 0; + break; + } + break; + case 2: + switch(joystick.direction) { + case UP: + select = 0; + break; + case DOWN: + select = 1; + break; + } + break; } - //snake_move(); + wait(0.1); + if (select == 0) { + lcd.clear(); + lcd.printString("SNAKE",27,0); + lcd.printString("Start Game",7,2); + lcd.printString("High Scores",7,3); + lcd.printString("Settings",7,4); + lcd.drawCircle(3,19,2,1); + lcd.refresh(); + wait(0.15); + if (butt1_flag == 1) { + butt1_flag = 0; + joystickTimer.detach(); + game(); + } + } else if (select == 1) { + lcd.clear(); + lcd.printString("SNAKE",27,0); + lcd.printString("Start Game", 7,2); + lcd.printString("High Scores",7,3); + lcd.printString("Settings",7,4); + lcd.drawCircle(3,27,2,1); + lcd.refresh(); + wait(0.15); + if (butt1_flag == 1) { + butt1_flag = 0; + HiScoreScreen(); + } + } else if (select == 2) { + lcd.clear(); + lcd.printString("SNAKE",27,0); + lcd.printString("Start Game", 7,2); + lcd.printString("High Scores",7,3); + lcd.printString("Settings",7,4); + lcd.drawCircle(3,35,2,1); + lcd.refresh(); + wait(0.15); + if (butt1_flag == 1) { + butt1_flag = 0; + settingsScreen(); + } + + + } + } +} + +void HiScoreScreen() +{ + lcd.clear(); + fp = fopen("/sd/hiscore.txt","r"); + while (butt2_flag == 0) { + + if (fp == NULL) { /// if high scores file not found + lcd.printString("High Scores:", 9,0); + + lcd.printString("No high", 21,3); + lcd.printString("scores found",9,4); + + sleep(); + + fclose(fp); + } else { + lcd.printString("High Scores:", 9,0); + lcd.printString("Level 1:", 9,1); + lcd.printString("Level 2:", 9,2); + lcd.printString("Level 3:", 9,3); + lcd.printString("Level 4:", 9,4); + lcd.printString("Level 5:", 9,5); + + int o; ///index of file + while (fscanf(fp, "%d,%d \n", &level_array[o],&HiScoreTable[o]) != EOF) { + o++; + } + + for (int lvl2 = 0; lvl2 <5 ; lvl2++) { + char lvlscore[14]; ///char to print highscore + sprintf(lvlscore,"%d",HiScoreTable[lvl2]); ///print highscore to char + lcd.printString ( lvlscore, 64, (lvl2+1)); ///print highscore on screen + } + } + fclose(fp); + lcd.refresh(); + sleep(); + + } + + if (butt2_flag == 1) { + butt2_flag = 0; + main_menu(); + butt1_flag = 0; } - +} - void food_pos() { - srand(time(NULL)); - fx = rand() % (width - 3) + 2; // random x from 4 to width - 3 for x coordinate - fy = rand() % (height - 3) + 2; // random y from 4 to height - 3 for y coordinate +void settingsScreen() +{ + lcd.clear(); + lcd.printString("Settings",18,0); + int levelsel = 2; + while (butt2_flag == 0) { + switch(levelsel) { + case 1: + switch(joystick.direction) { + case RIGHT: + level = 2.0; + levelsel = 2; + break; + case LEFT: + level = 5.0; + levelsel = 5; + break; + } + break; + case 2: + switch(joystick.direction) { + case RIGHT: + level = 3.0; + levelsel = 3; + break; + case LEFT: + level = 1.0; + levelsel = 1; + break; + } + break; + case 3: + switch(joystick.direction) { + case RIGHT: + level = 4.0; + levelsel = 4; + break; + case LEFT: + level = 2.0; + levelsel = 2; + break; + } + break; + case 4: + switch(joystick.direction) { + case RIGHT: + level = 5.0; + levelsel = 5; + + break; + case LEFT: + level = 3.0; + levelsel = 3; + } + break; + case 5: + switch(joystick.direction) { + case RIGHT: + level = 1.0; + levelsel = 1; + break; + case LEFT: + level = 4.0; + levelsel = 4; + break; + } + break; + } + + if (level == 1) { + lcd.printString("Level: < 1 >",6,3); + levelcalc = 0.4; + lcd.refresh(); + sleep(); + } else if (level == 2) { + lcd.printString("Level: < 2 >",6,3); + levelcalc = 0.33; + lcd.refresh(); + sleep(); + } else if (level == 3) { + lcd.printString("Level: < 3 >",6,3); + levelcalc = 0.25; + lcd.refresh(); + sleep(); + } else if (level == 4) { + lcd.printString("Level: < 4 >",6,3); + levelcalc = 0.15; + lcd.refresh(); + sleep(); + } else if (level == 5) { + lcd.printString("Level: < 5 >",6,3); + levelcalc = 0.1; + lcd.refresh(); + sleep(); + } } - void main_menu() { - //brightnessTimer.attach(adjust_brightness,0.1); - joystickTimer.attach(joystick_pos,0.1); - int select = 0; - while (1) { - switch(select) { - case 0: - switch(joystick.direction) { - case UP: - select = 1; - break; - case DOWN: - select = 1; - break; - } - break; - case 1: - switch(joystick.direction) { - case UP: - select = 0; - break; - case DOWN: - select = 0; - break; - } - break; + if (butt2_flag == 1) { + butt2_flag = 0; + lcd.clear(); + butt1_flag = 0; + main_menu(); + } +} + +void gameOver_screen() +{ + gameTimer1.detach(); + gameTimer2.detach(); + + while (butt2_flag == 0) { + fp = fopen("/sd/hiscore.txt","r"); //read high score + wait(0.5); + lcd.clear(); + + lcd.printString("Game Over",15,1); + char scorebuffer[14]; + int length = sprintf(scorebuffer, "Score = %d",score); + if (length <=14) { + lcd.printString(scorebuffer,12,2); + } + + if (fp == NULL) { ///if high score file doesnt exist + fp = fopen("/sd/hiscore.txt","w"); /// create new high score + for (int lvl = 1; lvl < 6; lvl ++) { ///prints all level score as zero (initialize) + fprintf(fp,"%d,0 \n", lvl); } - wait(0.1); - if (select == 0) { - lcd.clear(); - lcd.printString("Start Game",7,0); - lcd.printString("Settings",7,1); - lcd.drawCircle(3,3,2,1); - lcd.refresh(); - } else if (select == 1) { - lcd.clear(); - lcd.printString("Start Game", 7,0); - lcd.printString("Settings",7,1); - lcd.drawCircle(3,11,2,1); - lcd.refresh(); + fprintf(fp,"%d,%d \n", level, score); /// print the score of the current game according to level + + lcd.printString("New Highscore!",0,4); + fclose(fp); + sleep(); + + if (butt2_flag == 1) { + butt2_flag = 0; + main_menu(); + gameTimer1.detach(); + gameTimer2.detach(); + butt1_flag = 0; + } + + } else { /// if file exists + rewind(fp); + int o; ///index of file, just for counter + while (fscanf(fp, "%d, %d \n", &level_array[o],&HiScoreTable[o]) != EOF) { //read file data into array + o++; + } + + if (score > HiScoreTable[(level - 1)]) { ///if current score is higher than HiScore(current level) + lcd.printString("New Highscore!",0,4); + + HiScoreTable[(level - 1)] = score; ///save high score in table + } + + + fp = fopen("/sd/hiscore.txt","w"); /// overwrite score file + for (int b = 0; b < 5; b++) { ///write table to SD file + fprintf(fp, "%d,%d \n",b,HiScoreTable[b]); + fclose(fp); + sleep(); + } + + if (butt2_flag == 1) { + butt2_flag = 0; + main_menu(); + gameTimer1.detach(); + gameTimer2.detach(); + butt1_flag = 0; } } + + } +} + +void gamePaused_screen() +{ + while(butt2_flag == 0) { + gameTimer1.detach(); + gameTimer2.detach(); + LED = 1; /// toggle LED to show game is paused + butt2_flag = 0; + lcd.drawRect (4,4,74,38,2); + lcd.drawRect (4,4,74,38,0); + lcd.printString ("Game Paused",8,1); + lcd.printString ("Press button",6,3); + lcd.printString ("to unpause.",9,4); + sleep(); + } + if (butt2_flag == 1) { + butt2_flag = 0; + lcd.clear(); + draw_screen(); + wait(0.5); + gameTimer1.attach(&snake_logic_1,(levelcalc)); + gameTimer2.attach(&draw_screen, 0.1); + LED = 0; } - int main() { - init_display(); - //brightnessTimer.attach(adjust_brightness,0.1); - joystickTimer.attach(joystick_pos,0.1); - calibrate_joystick(); - gamemode = 0; - //lcd.printString("Hello, World!",0,0); - //main_menu(); - red_led = 1; - game(); - /*while(1) { - - lcd.clear(); - if (joystick.direction == UP) { - lcd.printString ("UP",1,0); - } else if (joystick.direction == CENTRE) { - lcd.printString ("CENTRE",1,0); - } else if (joystick.direction == DOWN) { - lcd.printString ("DOWN",1,0); - } else if (joystick.direction == LEFT) { - lcd.printString ("LEFT",1,0); - } else if (joystick.direction == RIGHT) { - lcd.printString ("RIGHT",1,0); - } else { - lcd.printString ("UNKNOWN",1,0); - } - lcd.refresh(); - wait(1); - } - */ +} - } +void butt1_isr() +{ + butt1_flag = 1; +} + +void butt2_isr() +{ + butt2_flag = 1; +}