My ELEC2645 project. Nikollao Sulollari. 200804685
Dependencies: N5110 SoftPWM mbed
Fork of Treasure_Hunt by
main.h
- Committer:
- Nikollao
- Date:
- 2016-05-02
- Revision:
- 17:2d424db3975f
- Parent:
- 16:a6ca6858af24
- Child:
- 18:5405ee7e243b
File content as of revision 17:2d424db3975f:
/** @file main.h @brief Header file contains functions and variables @brief Treasure Hunt - Embedded Systems Project @brief Revision 1.0 @author Nikollao Sulollari @Date 26/03/2016 */ #ifndef MAIN_H #define MAIN_H #include "mbed.h" #include "N5110.h" #include "SoftPWM.h" #define DIRECTION_TOLERANCE 0.05 /** @nameSpace r_led @brief output for status of red LED */ DigitalOut r_led(LED_RED); /** @nameSpace g_led @brief output for status of green LED */ DigitalOut g_led(LED_GREEN); /** @nameSpace b_led @brief output for status of blue LED */ DigitalOut b_led(LED_BLUE); /** @nameSpace blue_led @brief output for status of blue LED, lights when game tool is loaded */ DigitalOut blue_led(PTA1); /** @nameSpace led_output @brief output for status of left tries for the user to win the game */ BusOut led_output(PTC2,PTA2,PTB23); /** @nameSpace lcd @brief object of the N5110 class */ N5110 lcd(PTE26 , PTA0 , PTC4 , PTD0 , PTD2 , PTD1 , PTC3); /** @nameSpace pc @brief serial connection between mbed and pc */ Serial pc(USBTX,USBRX); // K64F on-board switches InterruptIn sw2(SW2); InterruptIn sw3(SW3); /** @nameSpace xPot @brief read x-axis position from the value of the joystick */ AnalogIn xPot(PTB2); /** @nameSpace yPot @brief read y-axis position from the value of the joystick */ AnalogIn yPot(PTB3); /** @nameSpace button @brief interrupt executes an event triggered task */ InterruptIn button(PTB10); /** @nameSpace button @brief interrupt executes an event triggered task */ InterruptIn button1(PTB18); /** @nameSpace buzzer @brief create PWM signal to set buzzer duty cycle and period */ SoftPWM buzzer(PTB9); /** @nameSpace ticker @brief interrupt executes a time-triggered task */ Ticker ticker; /** @nameSpace game_ticker @brief interrupt executes a time-triggered task */ Ticker game_ticker; /** @nameSpace timeout @brief interrupt calls a function after a specified amount of time */ Timeout timeout; /** @nameSpace DirectionName @brief define joystick's direction based on its x,y values */ enum DirectionName { UP, DOWN, LEFT, RIGHT, CENTRE, UP_LEFT, UP_RIGHT, DOWN_LEFT, DOWN_RIGHT }; /** @nameSpace Joystick @brief create strcut Joystick */ typedef struct JoyStick Joystick; struct JoyStick { double x; /// current x value double x0; /// 'centred' x value double y; /// current y value double 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 main(); /** Displays an error message */ void error(); /** set-up serial port */ void init_serial(); /** set-up the on-board LEDs and switches */ void init_K64F(); /** Set-up random variables and game menu */ void init_game(); /** Set-up flag to 1 */ /** Set-up flag to 1 */ void timer_isr(); /** Set-up flag to 1 */ /** Set-up flag to 1 */ void game_timer_isr(); /** Set-up flag to 1 */ void sw2_isr(); /** Set-up flag to 1 */ void sw3_isr(); /** Set-up flag to 1 */ void button_isr(); /** Set-up flag to 1 */ void button1_isr(); /** Set-up flag to 1 */ void timeout_isr(); /** Set current position to default position of Joystick */ void calibrateJoystick(); /** Update the values of the joystick to get current position */ void updateJoystick(); /** Create an enemy rectangular shape */ void enemyRect(); /** Create circle shape enemy */ void enemyCircle(); /** creates the hero of the game */ void hero(); /** Shows the right direction */ void guidance(); /** Locates obstacles in the screen */ void obstacles(); /** Gets enemies depending on the level */ void enemies(); /** Get s vslue of the .y position, control menu */ int menu(); //testing void checkOverlap(); /** Check for intrersection @param i loops through x direction @param j loops through y direction @returns the number of pixels aroun the hero detected */ int intersection(int i, int j); //vars volatile int rectX; /*!< used to determine x-axis position of the rect enemy */ volatile int rectY ;/*!< used to determine y-axis position of the rect enemy */ volatile int circleX;/*!< used to determine x-axis position of the circular enemy */ volatile int circleY;/*!< used to determine y-axis position of the circular enemy */ volatile int heroX;/*!< used to move the hero along x-axis */ volatile int heroY;/*!< used to move the hero along y-axis */ volatile int level = 0; /*!< initiate the level difficulty of the game */ volatile int g_timer_flag = 0; /*!< set timer flag in the isr, timer trigger interrupt */ volatile int g_game_timer_flag = 0; /*!< set timer flag in the isr, timer trigger interrupt */ volatile int g_sw2_flag = 0; /*!< set timer flag in the isr, event trigger interrupt */ volatile int g_sw3_flag = 0; /*!< set timer flag in the isr, event trigger interrupt */ volatile int g_button_flag = 0; /*!< set flag in the isr, event trigger interrupt */ volatile int g_button1_flag = 0; /*!< set flag in the isr, event trigger interrupt */ volatile int option = 0; /*!< select option in menu based on Joystick's movement */ volatile int play = 0; /*!< counts the number of plays */ volatile int tries = 3;/*!< counts the number of trials */ volatile int n;/*!< number of pixels overlapping */ volatile float game_speed = 0.05; /*!< value is set to the ticker, allows user to select game speed */ int fsm[4] = {7,6,4,0}; /*!< array of elements in the FSM, each element is the output of the counter */ int fsm_state = 0; /*!< variable is used to access the array of states and produce an output */ int reset = 0; /*!< used to save current level of difficulty */ int objectX = 0; /*!< used to move obstacles in the x-axis */ int objectY = 20; /*!< used to move obstacles in the y-axis */ int state = 0; /*!< controls the direction of the objtacle */ int objectX1 = 58; /*!< used to move obstacles in the x-axis */ int state1 = 1; /*!< controls the direction of the objtacle */ //int menuY = 5; /*!< controls the position of the circle selector */ int speed = 1; /*!< controls the speed menu display */ bool normal=0; /*!< controls the lcd mode selection on menu */ bool sound = 0; /*!< determines if sound is on or off */ void enemies() { /// generate enemies in the screen depending on the level difficulty if (level == 0) { enemyRect(); //enemyCircle(); } else if (level == 1) { enemyRect(); //enemyCircle(); } else if (level == 2) { } else if (level == 3) { } enemyCircle(); enemyRect(); } void enemyRect() { ///generate rect shape enemy lcd.drawRect(rectX,rectY,5,4,1); rectX = rectX + rand()%4 - 2; rectY++; ///enemy moving towards hero if (rectY == 50){ rectY = 0; } if (rectX == 75 || rectX == 25) { rectX = 40+rand()%10 - 5; } } void hero() {///cotrol hero if (joystick.direction == RIGHT) { heroX--; } else if (joystick.direction == LEFT){ heroX++; } else { heroX = heroX; } if (joystick.direction == UP) { heroY--; } else if (joystick.direction == DOWN) { heroY++; } else { heroY = heroY; } if (joystick.direction == UP_LEFT) { heroY--; heroX++; } else if (joystick.direction == UP_RIGHT) { heroY--; heroX--; } else if (joystick.direction == DOWN_RIGHT) { heroY++; heroX--; } else if (joystick.direction == DOWN_LEFT) { heroY++; heroX++; } ///set x-axis boundaries so hero does not go out of screen if (heroX > 40) { heroX = -40; } if (heroX < -45) { heroX = 35; } if (heroY < -45) { ///if hero has reached the top of the screen heroY = 0; ///hero goes back to the bottom of the screen level++; ///level increases by 1 } if (heroY >= 0) {/// hero cannot go to previous level heroY = 0; } ///draw hero lcd.drawLine(40+heroX, 47+heroY, 48+heroX, 43+heroY,1); lcd.drawLine(40+heroX, 43+heroY,48+heroX, 47+heroY,1); lcd.drawLine(44+heroX, 45+heroY,44+heroX, 41+heroY,1); lcd.drawCircle(44+heroX, 39+heroY,2,0); } void enemyCircle() {///generate circle shape enemy lcd.drawCircle(circleX,circleY,4,1); circleY = circleY + rand() %4 - 2; if (circleY <= 10) { circleY = 20; }if (circleY >= 35) { circleY = 35; } if (circleX > 84) { circleX = 0; } circleX++; ///enemy moving towards hero } void init_game() { ///initialise game srand(time(NULL)); /// generate random numbers rectY = 0; /// init rectX, rectY rectX = rand() %40 + 20; circleY = rand() %20 + 10; /// init circleX, circleY circleX = 0; lcd.setBrightness(0.5); // put LED backlight on 50% lcd.printString("Welcome to",11,1); lcd.printString("Treasure Hunt!",1,3); lcd.refresh(); //timeout.attach(&timeout_isr,3); //sleep(); wait(3); lcd.clear(); } void guidance() { /// show arrow to act as guidance towards the treasure if (level < 7) { ///check level of difficulty lcd.drawLine(42,0,42,4,1); lcd.drawLine(42,0,40,2,1); lcd.drawLine(42,0,44,2,1); } else if (level == 7) { lcd.printString("F",42,0); /// print the treasure icon } else if (level == 8) { ticker.detach(); lcd.clear(); lcd.printString("Well done!",0,0); lcd.refresh(); wait(2); lcd.clear(); lcd.printString("Play again",0,0); lcd.drawCircle(70,4,2,1); lcd.refresh(); g_button_flag = 0; while(1) { if (g_button_flag) { g_button_flag = 0; level = 0; // play++; lcd.clear(); main(); r_led = 0; lcd.refresh(); } sleep(); } } } void obstacles() { /// place obstacles in the screen /// as level difficulty increases, more obstacles are added if (level == 1) { lcd.drawRect(10,15,2,2,1); lcd.drawRect(74,15,2,2,1); } else if (level == 2) { lcd.drawRect(10,15,2,2,1); lcd.drawRect(74,15,2,2,1); lcd.drawRect(10,28,2,2,1); lcd.drawRect(74,28,2,2,1); } else if (level == 3) { lcd.drawRect(5,12,2,2,1); lcd.drawRect(79,12,2,2,1); lcd.drawRect(5,30,2,2,1); lcd.drawRect(79,30,2,2,1); lcd.drawRect(28,12,2,2,1); lcd.drawRect(52,12,2,2,1); lcd.drawRect(28,30,2,2,1); lcd.drawRect(52,30,2,2,1); } else if (level == 4) { lcd.drawRect(5 ,12+ rand() %4 - 2,2,2,1); lcd.drawRect(79 + rand() %4 - 2,12 + rand() %4 - 2,2,2,1); lcd.drawRect(5+ rand() %4 - 2,30 ,2,2,1); lcd.drawRect(79 + rand() %4 - 2,30,2,2,1); lcd.drawRect(28 + rand() %4 - 2,12+ rand() %4,2,2,1); lcd.drawRect(52,12 + rand() %4 - 2,2,2,1); lcd.drawRect(28,30 + rand() %4 - 2,2,2,1); lcd.drawRect(52 + rand() %4 - 2,30,2,2,1); } if (objectX == 0) { ///check position of obstacle state = 0; ///assign states to the position of the obstacle } else if (objectX == 60) { state = 1; } else { state = state; } if (state == 0) { ///if state is 0 increase position on x-axis objectX++; } else { objectX--; ///else if state is 1 decrease position on x-axis } if (objectX1 == 68) { state1 = 1; } else if (objectX1 == 10) { state1 = 0; } if (state1 == 1) { objectX1--; } else if (state1 == 0) { objectX1++; } objectY = objectY + rand() %4 - 2; ///set poistion of obstacle on y-axis to be valuable ///keep moving object within boundaries if (objectY <= 10) { objectY = 10; } if (objectY >= 37) { objectY = 37; } if ( level == 5) { lcd.drawLine(15,10,15,37,1); lcd.drawLine(71,10,71,37,1); lcd.drawRect(11+objectX,objectY,2,2,1); ///draw obstacle lcd.drawRect(80,10,2,2,1); lcd.drawRect(5,10,2,2,1); lcd.drawRect(80,20,2,2,1); lcd.drawRect(5,20,2,2,1); lcd.drawRect(80,30,2,2,1); lcd.drawRect(5,30,2,2,1); } else if (level == 6) { lcd.drawLine(15,10,15,37,1); ///draw boundaries lcd.drawLine(71,10,71,37,1); lcd.drawRect(11+objectX,objectY,2,2,1); /// draw moving obstacles on screen lcd.drawRect(objectX1,10+objectY,2,2,1); lcd.drawRect(80,10,2,2,1); ///draw stable obstacles lcd.drawRect(5,10,2,2,1); lcd.drawRect(80,20,2,2,1); lcd.drawRect(5,20,2,2,1); lcd.drawRect(80,30,2,2,1); lcd.drawRect(5,30,2,2,1); } else if (level == 7) { /* lcd.drawLine(50,15,30,15,1); lcd.drawLine(30,15,30,35,1); lcd.drawLine(30,25,45,25,1); */ } } void calibrateJoystick() { // 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 = RIGHT; } else if ( joystick.x < DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) { joystick.direction = LEFT; } else if (joystick.y > DIRECTION_TOLERANCE && joystick.x < DIRECTION_TOLERANCE) { joystick.direction = UP_LEFT; } else if (joystick.y > DIRECTION_TOLERANCE && joystick.x > DIRECTION_TOLERANCE) { joystick.direction = UP_RIGHT; } else if (joystick.y < DIRECTION_TOLERANCE && joystick.x < DIRECTION_TOLERANCE) { joystick.direction = DOWN_LEFT; } else if (joystick.y < DIRECTION_TOLERANCE && joystick.x > DIRECTION_TOLERANCE) { joystick.direction = DOWN_RIGHT; } } int menu() { while(1) { if (g_game_timer_flag) { g_game_timer_flag = 0; updateJoystick(); lcd.clear(); lcd.printString("Start Game",0,0); ///print the main lcd.printString("Settings",0,2); lcd.printString("Exit",0,4); //lcd.drawCircle(70,4,2,1); switch (joystick.direction) { ///check the direction of joystick case UP: option--; break; case DOWN: option++; break; } if (option < 0) { option = 2; } if (option > 2) { option = 0; } if (option == 0) { ///selection in menu depends on the value of int option lcd.drawCircle(70,4,2,1); } else if (option == 1) { lcd.drawCircle(55,20,2,1); } else if (option == 2) { lcd.drawCircle(35,35,2,1); } if(g_button_flag) { /// if button is pressed g_button_flag = 0; ///reset flag if (option == 0) { ///break the while loop, start game break; } else if (option == 1) { ///enter settings menu option = 0; while(1) { if (g_game_timer_flag) { g_game_timer_flag = 0; updateJoystick(); ///update joystick position lcd.clear(); if (normal) { if (sound) { lcd.printString("Game speed",0,0); ///print settings menu lcd.printString("Lcd:Inverse",0,1); lcd.printString("Sound:ON",0,2); lcd.printString("Back",0,3); } else { lcd.printString("Game speed",0,0); ///print settings menu lcd.printString("Lcd:Inverse",0,1); lcd.printString("Sound:OFF",0,2); lcd.printString("Back",0,3); } } else { if (sound) { lcd.printString("Game speed",0,0); ///print settings menu lcd.printString("Lcd: Normal",0,1); lcd.printString("Sound: ON",0,2); lcd.printString("Back",0,3); } else { lcd.printString("Game speed",0,0); ///print settings menu lcd.printString("Lcd: Normal",0,1); lcd.printString("Sound: OFF",0,2); lcd.printString("Back",0,3); } } switch (joystick.direction) { case UP: option--; break; case DOWN: option++; break; case CENTRE: option = option; break; } if (option < 0) { ///if selector is on the top of the screen and UP is pressed, selector goes to the bottom option = 3; } if (option > 3) { ///if selector is on the bottom of the screen and DOWN is pressed, selector goes to the top option = 0; } /// menu selection depends on the position of the Joystick if (option == 0) { lcd.drawCircle(70,4,2,1); } else if (option == 1) { lcd.drawCircle(70,12,2,1); } else if (option == 2) { lcd.drawCircle(70,20,2,1); } else { lcd.drawCircle(35,27,2,1); } if (g_button_flag) { ///if button is pressed g_button_flag = 0; ///reset button if (option == 0) { /// if user selects to modify speed of the game while(1) { ///set speed of the game if (g_game_timer_flag) { g_game_timer_flag = 0; updateJoystick(); lcd.clear(); if (speed == 0) { lcd.printString("Slow!",0,0); ///print game speed menu lcd.printString("Normal",0,1); lcd.printString("Fast",0,2); lcd.printString("Back",0,3); } else if (speed == 1) { lcd.printString("Slow",0,0); ///print game speed menu lcd.printString("Normal!",0,1); lcd.printString("Fast",0,2); lcd.printString("Back",0,3); } else if (speed == 2) { lcd.printString("Slow",0,0); ///print game speed menu lcd.printString("Normal",0,1); lcd.printString("Fast!",0,2); lcd.printString("Back",0,3); } switch (joystick.direction) { case UP: option--; break; case DOWN: option++; break; case CENTRE: option = option; break; } if (option < 0) { option = 3; } if (option > 3) { option = 0; } if (option == 0) { lcd.drawCircle(70,4,2,1); } else if (option == 1) { lcd.drawCircle(55,12,2,1); } else if (option == 2) { lcd.drawCircle(35,20,2,1); } else { lcd.drawCircle(35,27,2,1); } if (g_button_flag) { g_button_flag = 0; if (option == 0) { game_speed = 0.1; speed = 0; } else if (option == 1) { game_speed = 0.05; speed = 1; } else if (option == 2) { game_speed = 0.04; speed = 2; } else if (option == 3) { break; } } lcd.refresh(); } sleep(); } } else if (option == 1) { /// Lcd inverse mode normal =! normal; if (normal) { lcd.inverseMode(); } else { lcd.normalMode(); } } else if (option == 2) { ///select sound or not sound =! sound; if (sound) buzzer.write(0.5); else buzzer.write(0.0); // buzzer.period(1/400); } else if(option == 3) { ///go back to main menu break; } } lcd.refresh(); } sleep(); } } else if (option == 2) { ///turn off LED lcd.clear(); lcd.turnOff(); while(1) { deepsleep(); } } } lcd.refresh(); } sleep(); } } int intersection(int i, int j) { /// check for overlap between enemies and hero n=0; if (lcd.getPixel(i-1,j-1)!=0) //pixel to the top-left n++; // increase n by 1 if (lcd.getPixel(i-1,j)!=0) //pixel to the left n++; // increase n by 1 if (lcd.getPixel(i-1,j+1)!=0) //pixel to the bottom-left n++; // increase n by 1 if (lcd.getPixel(i,j-1)!=0) // pixel to the top n++; // increase n by 1 if (lcd.getPixel(i,j+1)!=0) //pixel to the bottom n++; // increase n by 1 if (lcd.getPixel(i+1,j-1)!=0) //pixel to the top-right n++; // increase n by 1 if (lcd.getPixel(i+1,j)!=0) // pixel to the right n++; // increase n by 1 if (lcd.getPixel(i+1,j+1)!=0) //pixel to the bottom right n++; // increase n by 1 return n; } void checkOverlap() { for (int i=40+heroX; i<50+heroX; i++) { for (int j=35+heroY; j<48+heroY; j++) { int check = intersection(i,j); //lcd.setPixel(i,j); char bit[50]; sprintf(bit,"Pixels: %d",check); for(int i = 40; i < 45; i++) { for (int j = -5; i < 5; j++) { if (check > 6) { check = 6; } } } if (check > 7) { tries--; //if tries lcd.printString("BANG!",0,0); lcd.refresh(); wait(2); lcd.clear(); if (tries == 2) { lcd.printString("Ready.",20,1); lcd.refresh(); wait(0.5); lcd.printString("Ready..",20,1); lcd.refresh(); wait(0.5); lcd.printString("Ready...",20,1); lcd.refresh(); wait(1); lcd.printString("GO!",31,2); lcd.refresh(); wait(1); lcd.clear(); fsm_state = 1; ///2 lives left } else if (tries == 1) { lcd.clear(); lcd.printString("Last Chance!",10,2); lcd.refresh(); wait(1); fsm_state = 2; //1 life left } else if (tries == 0) { fsm_state = 3; led_output=fsm[fsm_state]; lcd.clear(); lcd.printString("Game Over!",0,0); lcd.refresh(); wait(1); //ticker.detach(); lcd.clear(); lcd.printString("Play again",0,0); lcd.drawCircle(70,4,2,1); lcd.refresh(); g_button_flag = 0; while(1) { if (g_button_flag) { g_button_flag = 0; level = 0; fsm_state = 0; led_output=fsm[fsm_state]; lcd.clear(); main(); } sleep(); } } heroX = 0; heroY = 0; rectY = 0; circleX = 0; led_output=fsm[fsm_state]; } } } } void error() { /// display error message while (1) { lcd.printString("Error!",0,0); r_led = 0; wait(0.2); r_led = 1; wait(0.2); } } #endif