My ELEC2645 project. Nikollao Sulollari. 200804685

Dependencies:   N5110 SoftPWM mbed

Fork of Treasure_Hunt by ELEC2645 (2015/16)

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

Go to the documentation of this file.
00001 /**
00002 @file main.cpp
00003 @brief Game implementation
00004 
00005 */
00006 #include "main.h"
00007 #include "stdlib.h"
00008 
00009 int main(void)
00010 {
00011     lcd.init(); ///initialise LED
00012     init_K64F(); ///init K64F 
00013     init_serial(); ///initiate connection with PC port
00014     init_game(); ///initialize game
00015     led_output = fsm [fsm_state ]; ///set FSM to turn on LEDs
00016     calibrateJoystick(); ///calibrate joystick
00017 
00018     game_ticker.attach(&game_timer_isr,0.2); ///attach ticker for the menu different from the main ticker
00019     menu();
00020     game_ticker.detach();
00021     //timer.start();
00022 
00023     ticker.attach(&timer_isr,game_speed ); ///attach ticker with ISR. Speed is selected by the user
00024     reset  = level ; ///set reset = level to check later if level has increased
00025     g_button1_flag  = 0;
00026     timer.start();
00027     while (1) {
00028         
00029         if (g_timer_flag ) {///if timer flag is UP
00030 
00031             g_timer_flag  = 0; ///reset flag
00032             lcd.clear();
00033             if (reset  < level ) { ///if level has increased
00034                 g_button1_flag  = 0; ///reset weapon button
00035                 reset  = level ; ///update reset
00036                 rectY  = 0; ///set enemies to default position
00037                 circleX  = 0;
00038             }
00039             guidance(); ///get guidance
00040             hero(); ///call hero
00041             enemies(); ///generate enemies 
00042             obstacles(); ///generate obstacles
00043             //float count_time = timer.read();
00044             
00045             if (g_button1_flag ) { ///the blue LED indicates if the weapon is ready to use or not
00046                 blue_led = 0;    
00047             } else {
00048                 blue_led = 1;
00049             }
00050                 
00051             checkOverlap(); ///check is hero has overlapped with enemies or obstacles 
00052             updateJoystick(); ///update joystick
00053             lcd.refresh();
00054         }
00055         sleep();///use sleep and timer triggered interrupt to save power 
00056     }
00057 }
00058 
00059 
00060 //mbed functions
00061 
00062 
00063 void init_serial()
00064 {
00065     // set to highest baud - ensure terminal software matches
00066     pc.baud(115200);
00067 }
00068 
00069 void init_K64F()
00070 {
00071     // on-board LEDs are active-low, so set pin high to turn them off.
00072     r_led = 1;
00073     g_led = 1;
00074     b_led = 1;
00075 
00076     blue_led = 1;
00077 
00078     // since the on-board switches have external pull-ups, we should disable the internal pull-down
00079     // resistors that are enabled by default using InterruptIn
00080     sw2.mode(PullNone);
00081     sw3.mode(PullNone);
00082     
00083     button.rise(&button_isr); ///assign rise with ISR
00084     button1.rise(&button1_isr);
00085     button.mode(PullDown); ///use PullDown mode
00086     button1.mode(PullDown);
00087 }
00088 
00089 
00090 ///ISR functions
00091 void timer_isr ()
00092 {
00093     g_timer_flag  = 1;
00094 }
00095 
00096 void game_timer_isr()
00097 {
00098     g_game_timer_flag  = 1;
00099 }
00100 
00101 void sw2_isr()
00102 {
00103     g_sw2_flag  = 1;
00104 }
00105 
00106 void sw3_isr()
00107 {
00108     g_sw3_flag  = 1;
00109 }
00110 
00111 void button_isr()
00112 {
00113     g_button_flag  =1;
00114 }
00115 
00116 void button1_isr()
00117 {
00118 
00119     g_button1_flag  =1;
00120 }
00121 
00122 void timeout_isr()
00123 {
00124     if (button) {
00125         pc.printf("timeout \n");
00126     }
00127 }
00128 
00129 ///game functions
00130 
00131 void enemies()
00132 {
00133     /// generate enemies in the screen depending on the level of difficulty
00134     if (level  == 0) { ///generate enemies at level 0
00135 
00136         enemyRect();
00137         if (g_button1_flag  == 0) {
00138             enemyCircle();
00139         }
00140     } else if (level  == 1) {///generate enemies at level 1
00141 
00142         enemyRect();
00143         if (g_button1_flag  == 0) {
00144             enemyCircle();
00145         }
00146     } else if (level  == 2) {///generate enemies at level 2
00147 
00148         enemyRocket();
00149         if (g_button1_flag  == 0) {
00150             enemyCircle();
00151         }
00152     } else if (level  == 3) {///generate enemies at level 3
00153 
00154         enemyRect();
00155         if (g_button1_flag  == 0) {
00156             enemyCircle();
00157         }
00158     } else if (level  == 4) {///generate enemies at level 4
00159 
00160         enemyRect();
00161         if (g_button1_flag  == 0) {
00162             enemyCircle();
00163         }
00164     } else if (level  == 5) {///generate enemies at level 5
00165         enemyRocket();
00166         if (g_button1_flag  == 0) {
00167             enemyCircle();
00168         }
00169     } else if (level  == 6) {///generate enemies at level 6
00170         enemyRocket();
00171         if (g_button1_flag  == 0) {
00172             enemyCircle();
00173         }
00174     } else if (level  == 7) {///generate enemies at level 7
00175         enemyRocket();
00176         enemyCircle();
00177         if (g_button1_flag  == 1) {///if button1 is pressed don't allow to use at level 7
00178             g_button1_flag  = 0;
00179              lcd.clear();
00180             lcd.printString("Can't use now!",0,0);
00181             lcd.refresh();
00182             wait(1);
00183             lcd.clear();
00184         }
00185     }
00186 
00187 }
00188 
00189 void enemyRect()
00190 {
00191     ///generate rectangular shape enemy
00192     lcd.drawRect(rectX ,rectY ,5,4,1);
00193 
00194     rectX  = rectX  + rand()%4 - 2;
00195     rectY ++; ///enemy moving towards hero
00196 
00197     if (rectY  > 50) {///set boundaries for enemy position
00198         rectY  = 0;
00199     }
00200     if (rectX  > 75 || rectX  < 25) {
00201         rectX  = 40+rand()%6 - 3;
00202     }
00203 }
00204 
00205 void enemyRocket() { ///generate a "rocket-like" enemy
00206     
00207     lcd.drawRect(rectX ,rectY ,2,7,1);
00208     lcd.drawCircle(rectX +1,rectY +1,2,1);
00209     lcd.drawLine(rectX -2,rectY +2,rectX ,rectY -1,1);
00210     lcd.drawLine(rectX +2,rectY +2,rectX ,rectY -1,1);
00211 
00212     rectX  = rectX  + rand()%4 - 2;
00213     rectY ++; ///enemy moving towards hero
00214 
00215     if (rectY  > 50) {///set boundaries for position of enemy
00216         rectY  = 0;
00217     }
00218     if (rectX  > 75 || rectX  < 10) {
00219         rectX  = 40+rand()%6 - 3;
00220     }
00221 }
00222 
00223 void enemyCircle()
00224 {
00225     ///generate circle shape enemy
00226     lcd.drawCircle(circleX ,circleY ,4,1);
00227     circleY  = circleY  + rand() %4 - 2;
00228 
00229     if (circleY  <= 10) { ///set the boundaries of the enemy
00230         circleY  = 20;
00231     }
00232     if (circleY  >= 35) {
00233         circleY  = 35;
00234     }
00235     if (circleX  > 84) {
00236         circleX  = 0;
00237     }
00238     circleX ++; ///enemy moving towards hero
00239 }
00240 void hero()
00241 {
00242     ///cotrol hero
00243     if (joystick.direction == RIGHT) { ///joystick direction points to the right
00244         heroX --;
00245     } else if (joystick.direction == LEFT) {///joystick direction points to the left
00246         heroX ++;
00247     } else {
00248         heroX  = heroX ;
00249     }
00250 
00251     if (joystick.direction == UP) {///joystick direction points to the top
00252         heroY --;
00253     } else if (joystick.direction == DOWN) {///joystick direction points down
00254         heroY ++;
00255     } else {
00256         heroY  = heroY ; ///joystick is centred
00257     }
00258 
00259     if (joystick.direction == UP_LEFT) { ///joystick direction points up and left
00260         heroY --;
00261         heroX ++;
00262     } else if (joystick.direction == UP_RIGHT) { ///joystick direction points up and right
00263         heroY --;
00264         heroX --;
00265     } else if (joystick.direction == DOWN_RIGHT) {///joystick direction points down and right
00266         heroY ++;
00267         heroX --;
00268     } else if (joystick.direction == DOWN_LEFT) {///joystick direction points down and left
00269         heroY ++;
00270         heroX ++;
00271     }
00272 
00273     ///set x-axis boundaries so hero does not go out of screen
00274     if (heroX  > 40) {
00275         heroX  = -40;
00276     }
00277     if (heroX  < -45) {
00278         heroX  = 35;
00279     }
00280     if (heroY  < -45) { ///if hero has reached the top of the screen
00281         heroY  = 0; ///hero goes back to the bottom of the screen
00282         g_button1_flag  = 0;
00283         level ++; ///increase level of the game
00284     }
00285 
00286     if (heroY  >= 0) {/// hero cannot go to previous level
00287         heroY  = 0;
00288     }
00289     ///draw hero
00290     lcd.drawLine(40+heroX , 47+heroY , 48+heroX , 43+heroY ,1); ///variables heroX and heroY are used to control the direction of the hero
00291     lcd.drawLine(40+heroX , 43+heroY ,48+heroX , 47+heroY ,1);
00292     lcd.drawLine(44+heroX , 45+heroY ,44+heroX , 41+heroY ,1);
00293     lcd.drawCircle(44+heroX , 39+heroY ,2,0);
00294 }
00295 
00296 void init_game()
00297 {
00298     ///initialise game
00299     srand(time(NULL)); /// generate random numbers
00300     rectY  = 0; /// init rectX, rectY
00301     rectX  = rand() %40 + 20;
00302     circleY  = rand() %20 + 10; /// init circleX, circleY
00303     circleX  = 0;
00304 
00305     lcd.setBrightness(0.5); // put LED backlight on 50%
00306     lcd.printString("Welcome to",11,1);
00307     lcd.printString("Treasure Hunt!",1,3);
00308     lcd.refresh();
00309     //timeout.attach(&timeout_isr,3);
00310    // sleep();
00311     wait(3); ///small delay prints welcome message
00312     lcd.clear();
00313 
00314 }
00315 void guidance()
00316 {
00317     if (level  < 7) {
00318         lcd.drawLine(42,0,40,2,1);
00319         lcd.drawLine(42,0,44,2,1);
00320         lcd.drawLine(42,0,42,3,1);   
00321     }
00322     /// function acts as guidance towards the treasure
00323      else if (level  == 7) {
00324 
00325         lcd.printString("F",42,0); /// print the treasure icon
00326     } else if (level  == 8) {
00327         
00328         timer.stop(); ///stop timer
00329         timer.reset();
00330         float win_time = timer.read();///value reads the time taken to win the game
00331         char win[80]; ///create an array of chars
00332         sprintf(win,"Time:%.2f sec",win_time); ///create string
00333         ticker.detach();
00334         game_ticker.attach(&game_timer_isr,0.2); 
00335         lcd.clear();
00336         lcd.printString("Well done!",0,0);
00337         lcd.refresh();
00338         wait(2);
00339         lcd.clear();
00340         lcd.printString(win,0,0); ///print the time taken to win the game on screen
00341         wait(3);
00342         lcd.clear();
00343         lcd.printString("Play again!",0,0); ///provide play again option
00344         lcd.drawCircle(70,4,2,1);
00345         lcd.refresh();
00346         g_button_flag  = 0;
00347 
00348         while(1) {
00349             if  (g_button1_flag ) { ///if button1 is pressed
00350                 ///reset
00351                 g_button1_flag  = 0;
00352                 level  = 0;
00353                 lcd.clear();
00354                 main();
00355                 r_led = 0;
00356                 lcd.refresh();
00357             }
00358             sleep();
00359         }
00360     }
00361 }
00362 
00363 void obstacles()
00364 {
00365     /// place obstacles in the screen
00366     /// as level difficulty increases, more obstacles are added
00367     
00368     if (level  == 0) { ///obstacles are located in the ground and they change from one level to another
00369 
00370         lcd.drawRect(10,15,2,2,1);
00371         lcd.drawRect(74,15,2,2,1);
00372     } else if (level  == 1) {
00373 
00374         lcd.drawRect(10,15,2,2,1);
00375         lcd.drawRect(74,15,2,2,1);
00376         lcd.drawRect(10,28,2,2,1);
00377         lcd.drawRect(74,28,2,2,1);
00378     } else if (level  == 2) {
00379 
00380         lcd.drawCircle(25,25,5,0);
00381         lcd.drawCircle(65,25,5,0);
00382         lcd.drawCircle(45,11,3,1);
00383         lcd.drawCircle(25,25,3,1);
00384         lcd.drawCircle(65,25,3,1);
00385         lcd.drawRect(80,2,2,42,1);
00386         lcd.drawRect(2,2,2,42,1);
00387 
00388     } else if (level  == 3) {
00389 
00390         lcd.drawRect(5,12,2,2,1);
00391         lcd.drawRect(79,12,2,2,1);
00392         lcd.drawRect(5,30,2,2,1);
00393         lcd.drawRect(79,30,2,2,1);
00394         lcd.drawRect(28,12,2,2,1);
00395         lcd.drawRect(52,12,2,2,1);
00396         lcd.drawRect(28,30,2,2,1);
00397         lcd.drawRect(52,30,2,2,1);
00398     } else if (level  == 4) {
00399 
00400         lcd.drawRect(5+rand() %4 - 2 ,12+rand() %4 - 2,2,2,1); ///make obstacles moveable by adding a small random variance in position
00401         lcd.drawRect(79 + rand() %4 - 2,12 + rand() %4 - 2,2,2,1);
00402         lcd.drawRect(5+ rand() %4 - 2,30+rand() %4 - 2 ,2,2,1);
00403         lcd.drawRect(79 + rand() %4 - 2,30+rand() %4 - 2,2,2,1);
00404         lcd.drawRect(28 + rand() %4 - 2,12+ rand() %4,2,2,1);
00405         lcd.drawRect(52+rand() %4 - 2,12 + rand() %4 - 2,2,2,1);
00406         lcd.drawRect(28+rand() %4 - 2,30 + rand() %4 - 2,2,2,1);
00407         lcd.drawRect(52 + rand() %4 - 2,30+ rand() %4,2,2,1);
00408     }
00409     if (objectX  == 0) { ///check position of obstacle
00410         state  = 0; ///assign states to the position of the obstacle
00411     } else if (objectX  == 60) {
00412         state  = 1;
00413     } else {
00414         state  = state ;
00415     }
00416     if (state  == 0) { ///if state is 0 increase position on x-axis
00417         objectX ++;
00418     } else {
00419         objectX --; ///else if state is 1 decrease position on x-axis
00420     }
00421 
00422     if (objectX1  == 68) {
00423 
00424         state1  = 1;
00425     } else if (objectX1  == 10) {
00426         state1  = 0;
00427     }
00428     if (state1  == 1) {
00429         objectX1 --;
00430     } else if (state1  == 0) {
00431         objectX1 ++;
00432     }
00433     objectY  = objectY  + rand() %4 - 2; ///set poistion of obstacle on y-axis to be valuable
00434     ///keep moving object within boundaries
00435     if (objectY  <= 10) {
00436         objectY  = 10;
00437     }
00438     if (objectY  >= 37) {
00439         objectY  = 37;
00440     }
00441     if ( level  == 5) {
00442 
00443         lcd.drawLine(15,10,15,37,1);
00444         lcd.drawLine(71,10,71,37,1);
00445 
00446         lcd.drawRect(11+objectX ,objectY ,2,2,1); ///draw obstacle
00447 
00448         lcd.drawRect(80,10,2,2,1);
00449         lcd.drawRect(5,10,2,2,1);
00450         lcd.drawRect(80,20,2,2,1);
00451         lcd.drawRect(5,20,2,2,1);
00452         lcd.drawRect(80,30,2,2,1);
00453         lcd.drawRect(5,30,2,2,1);
00454 
00455     } else if (level  == 6) {
00456 
00457         lcd.drawLine(15,10,15,37,1); ///draw boundaries
00458         lcd.drawLine(71,10,71,37,1);
00459 
00460         lcd.drawRect(11+objectX ,objectY ,2,2,1); /// draw moving obstacles on screen
00461         lcd.drawRect(objectX1 ,10+objectY ,2,2,1);
00462         lcd.drawRect(80,10,2,2,1); ///draw stable obstacles
00463         lcd.drawRect(5,10,2,2,1);
00464         lcd.drawRect(80,20,2,2,1);
00465         lcd.drawRect(5,20,2,2,1);
00466         lcd.drawRect(80,30,2,2,1);
00467         lcd.drawRect(5,30,2,2,1);
00468     } else if (level  == 7) {
00469         lcd.printString("??",65,0);
00470 
00471        lcd.drawRect(1,23,82,2,1);
00472        if (button && heroX  <-30) {
00473             g_button_flag  = 0;
00474             heroX  = -30;
00475             heroY  = -30;  
00476         }
00477            
00478         pc.printf("x = %d , y = %d \n",heroX ,heroY );
00479     }
00480 }
00481 
00482 
00483 void calibrateJoystick()
00484 {
00485     // must not move during calibration
00486     joystick.x0 = xPot;  // initial positions in the range 0.0 to 1.0 (0.5 if centred exactly)
00487     joystick.y0 = yPot;
00488 }
00489 void updateJoystick()
00490 {
00491     // read current joystick values relative to calibrated values (in range -0.5 to 0.5, 0.0 is centred)
00492     joystick.x = xPot - joystick.x0;
00493     joystick.y = yPot - joystick.y0;
00494     // read button state
00495     joystick.button = button;
00496 
00497     // calculate direction depending on x,y values
00498     // tolerance allows a little lee-way in case joystick not exactly in the stated direction
00499     if ( fabs(joystick.y) < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
00500         joystick.direction = CENTRE;
00501     } else if ( joystick.y > DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
00502         joystick.direction = UP;
00503     } else if ( joystick.y < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
00504         joystick.direction = DOWN;
00505     } else if ( joystick.x > DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
00506         joystick.direction = RIGHT;
00507     } else if ( joystick.x < DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
00508         joystick.direction = LEFT;
00509     } else if (joystick.y > DIRECTION_TOLERANCE  && joystick.x  < DIRECTION_TOLERANCE) {
00510         joystick.direction = UP_LEFT;
00511     } else if (joystick.y > DIRECTION_TOLERANCE && joystick.x > DIRECTION_TOLERANCE) {
00512         joystick.direction = UP_RIGHT;
00513     } else if (joystick.y < DIRECTION_TOLERANCE && joystick.x < DIRECTION_TOLERANCE) {
00514         joystick.direction = DOWN_LEFT;
00515     }   else if (joystick.y < DIRECTION_TOLERANCE && joystick.x > DIRECTION_TOLERANCE) {
00516         joystick.direction = DOWN_RIGHT;
00517     }
00518 }
00519 
00520 void menu()
00521 {
00522     while(1) {
00523         if (g_game_timer_flag ) {
00524             g_game_timer_flag  = 0;
00525 
00526             updateJoystick();
00527             lcd.clear();
00528 
00529             lcd.printString("Start Game",0,0); ///print the main
00530             lcd.printString("Settings",0,2);
00531             lcd.printString("Exit",0,4);
00532             //lcd.drawCircle(70,4,2,1);
00533             lcd.refresh();
00534             switch (joystick.direction) { ///check the direction of joystick
00535                 case UP:
00536                     option --;
00537                     break;
00538                 case DOWN:
00539                     option ++;
00540                     break;
00541             }
00542             if (option  < 0) { /// if the last (down) option is set for selection and user presses joystick down, selector moves at the top
00543                 option  = 2;
00544             }
00545             if (option  > 2) { /// if the first (up) option is set for selection and user presses joystick up, selector moves at the bottom
00546                 option  = 0;
00547             }
00548 
00549             if (option  == 0) { ///selection in menu depends on the value of int option
00550                 lcd.drawCircle(70,4,2,1);
00551             } else if (option  == 1) {
00552                 lcd.drawCircle(55,20,2,1);
00553             } else if (option  == 2) {
00554                 lcd.drawCircle(35,35,2,1);
00555             }
00556 
00557             if(g_button_flag ) { /// if button is pressed
00558 
00559                 g_button_flag  = 0; ///reset flag
00560 
00561                 if (option  == 0) { ///break the while loop, start game
00562                     break;
00563                 }
00564 
00565                 else if (option  == 1) { ///enter settings menu
00566 
00567                     option  = 0;
00568 
00569                     while(1) {
00570                         if (g_game_timer_flag ) {
00571                             g_game_timer_flag  = 0;
00572 
00573                             updateJoystick(); ///update joystick position
00574                             lcd.clear();
00575                             if (normal ) {
00576                                 if (sound ) {
00577                                     lcd.printString("Game speed",0,0);  ///print settings menu
00578                                     lcd.printString("Lcd:Inverse",0,1);
00579                                     lcd.printString("Sound:ON",0,2);
00580                                     lcd.printString("Back",0,4);
00581                                 } else {
00582                                     lcd.printString("Game speed",0,0);  ///print settings menu
00583                                     lcd.printString("Lcd:Inverse",0,1);
00584                                     lcd.printString("Sound:OFF",0,2);
00585                                     lcd.printString("Back",0,4);
00586                                 }
00587                             } else {
00588                                 if (sound ) {
00589                                     lcd.printString("Game speed",0,0);  ///print settings menu
00590                                     lcd.printString("Lcd:Normal",0,1);
00591                                     lcd.printString("Sound:ON",0,2);
00592                                     lcd.printString("Back",0,4);
00593                                 } else {
00594                                     lcd.printString("Game speed",0,0);  ///print settings menu
00595                                     lcd.printString("Lcd:Normal",0,1);
00596                                     lcd.printString("Sound:OFF",0,2);
00597                                     lcd.printString("Back",0,4);
00598                                 }
00599                             }
00600                             switch (joystick.direction) {
00601                                 case UP:
00602                                     option --;
00603                                     break;
00604                                 case DOWN:
00605                                     option ++;
00606                                     break;
00607                                 case CENTRE:
00608                                     option  = option ;
00609                                     break;
00610                             }
00611                             if (option  < 0) { ///if selector is on the top of the screen and UP is pressed, selector goes to the bottom
00612                                 option  = 3;
00613                             }
00614                             if (option  > 3) { ///if selector is on the bottom of the screen and DOWN is pressed, selector goes to the top
00615                                 option  = 0;
00616                             }
00617 
00618                             /// menu selection depends on the position of the Joystick
00619                             if (option  == 0) {
00620                                 lcd.drawCircle(70,4,2,1);
00621                             } else if (option  == 1) {
00622                                 lcd.drawCircle(70,12,2,1);
00623                             } else if (option  == 2) {
00624                                 lcd.drawCircle(70,20,2,1);
00625                             } else {
00626                                 lcd.drawCircle(35,36,2,1);
00627                             }
00628                             if (g_button_flag ) { ///if button is pressed
00629                                 g_button_flag  = 0; ///reset button
00630 
00631                                 if (option  == 0) { /// if user selects to modify speed of the game
00632 
00633                                     while(1) { ///set speed of the game
00634 
00635                                         if (g_game_timer_flag ) {
00636                                             g_game_timer_flag  = 0;
00637                                             updateJoystick();
00638                                             lcd.clear();
00639                                             if (speed  == 0) {
00640                                                 lcd.printString("Slow<",0,0); ///print game speed menu
00641                                                 lcd.printString("Normal",0,1);
00642                                                 lcd.printString("Fast",0,2);
00643                                                 lcd.printString("Back",0,4);
00644                                             } else if (speed  == 1) {
00645                                                 lcd.printString("Slow",0,0); //print game speed menu
00646                                                 lcd.printString("Normal<",0,1);
00647                                                 lcd.printString("Fast",0,2);
00648                                                 lcd.printString("Back",0,4);
00649                                             } else if (speed  == 2) {
00650                                                 lcd.printString("Slow",0,0); //print game speed menu
00651                                                 lcd.printString("Normal",0,1);
00652                                                 lcd.printString("Fast<",0,2);
00653                                                 lcd.printString("Back",0,4);
00654                                             }
00655 
00656                                             switch (joystick.direction) {
00657                                                 case UP:
00658                                                     option --;
00659                                                     break;
00660                                                 case DOWN:
00661                                                     option ++;
00662                                                     break;
00663                                                 case CENTRE:
00664                                                     option  = option ;
00665                                                     break;
00666                                             }
00667                                             if (option  < 0) {
00668                                                 option  = 3;
00669                                             }
00670                                             if (option  > 3) {
00671                                                 option  = 0;
00672                                             }
00673 
00674                                             if (option  == 0) {
00675                                                 lcd.drawCircle(70,4,2,1);
00676                                             } else if (option  == 1) {
00677                                                 lcd.drawCircle(55,12,2,1);
00678                                             } else if (option  == 2) {
00679                                                 lcd.drawCircle(35,20,2,1);
00680                                             } else {
00681                                                 lcd.drawCircle(35,36,2,1);
00682                                             }
00683 
00684                                             if (g_button_flag ) {
00685                                                 g_button_flag  = 0;
00686 
00687                                                 if (option  == 0) {
00688                                                     game_speed  = 0.1; ///slow
00689                                                     speed  = 0;
00690                                                 } else if (option  == 1) {
00691                                                     game_speed  = 0.05; ///normal
00692                                                     speed  = 1;
00693                                                 } else if (option  == 2) {
00694                                                     game_speed  = 0.04; ///fast
00695                                                     speed  = 2;
00696                                                 } else if (option  == 3) {
00697                                                     break;
00698                                                 }
00699                                             }
00700                                             lcd.refresh();
00701                                         }
00702                                         sleep();
00703                                     }
00704                                 } else if (option  == 1) { /// Lcd inverse mode
00705                                     normal  =! normal ;
00706                                     if (normal ) {
00707                                         lcd.inverseMode();
00708                                     } else {
00709                                         lcd.normalMode();
00710                                     }
00711                                 } else if (option  == 2) { ///select  sound or not
00712 
00713                                     sound  =! sound ;
00714 
00715                                     if (sound ) {
00716                                         //buzzer.write(0.5);
00717                                        // buzzer.period(1/4000);
00718                                     }
00719                                     else {
00720                                         buzzer.write(0.0);
00721                                     }
00722                                     // buzzer.period(1/400);
00723                                 } else if(option  == 3) { ///go back to main menu
00724                                     break;
00725                                 }
00726                             }
00727                             lcd.refresh();
00728                         }
00729                         sleep();
00730                     }
00731                 } else if (option  == 2) { ///turn off LED
00732                     lcd.clear();
00733                     lcd.turnOff();
00734                     while(1) {
00735                         deepsleep();
00736                     }
00737                 }
00738             }
00739             lcd.refresh();
00740         }
00741         sleep();
00742     }
00743 }
00744 
00745 int intersection(int i, int j)
00746 {
00747     /// check for overlap between enemies and hero
00748     n =0;
00749 
00750     if (lcd.getPixel(i-1,j-1)!=0) //pixel to the top-left
00751         n ++; // increase n by 1
00752     if (lcd.getPixel(i-1,j)!=0) //pixel to the left
00753         n ++; // increase n by 1
00754     if (lcd.getPixel(i-1,j+1)!=0) //pixel to the bottom-left
00755         n ++; // increase n by 1
00756     if (lcd.getPixel(i,j-1)!=0) // pixel to the top
00757         n ++; // increase n by 1
00758     if (lcd.getPixel(i,j+1)!=0) //pixel to the bottom
00759         n ++; // increase n by 1
00760     if (lcd.getPixel(i+1,j-1)!=0) //pixel to the top-right
00761         n ++; // increase n by 1
00762     if (lcd.getPixel(i+1,j)!=0) // pixel to the right
00763         n ++; // increase n by 1
00764     if (lcd.getPixel(i+1,j+1)!=0) //pixel to the bottom right
00765         n ++; // increase n by 1
00766     return n ;
00767 }
00768 
00769 void checkOverlap()
00770 {
00771 
00772     for (int i=40+heroX ; i<50+heroX ; i++) { ///loop follows the hero and checks for overlap around him
00773         for (int j=35+heroY ; j<48+heroY ; j++) {
00774 
00775             int check = intersection(i,j); ///int gets number of pixels around the hero
00776             //lcd.setPixel(i,j);
00777             char bit[50];
00778             sprintf(bit,"Pixels: %d",check);
00779 
00780 
00781             for(int i = 40; i < 50; i++) { ///provides safety if hero is in default position he doesn't get killed by enemies
00782                 for (int j = 35; j < 47; j++) {
00783 
00784                     if (lcd.getPixel(i,j) && check > 6) { ///6 is the offset of the neigbours, as hero has his own neighbours pixels 
00785                         check = 6;
00786                     }
00787                 }
00788             }
00789             if (check > 7) {
00790                 tries --;
00791                 //if tries
00792                 lcd.printString("BANG!",0,0); ///Bang message is displayed when overlap has occured
00793                 if (sound ) {
00794                     buzzer.write(0.5);
00795                     //buzzer.pulsewidth(0.9);
00796                 } else {
00797                     buzzer.write(0.0);
00798                 }
00799                 lcd.refresh();
00800                 wait(2);
00801                 lcd.clear();
00802 
00803                 if (tries  == 2) {
00804                     
00805                     g_button1_flag  = 0;
00806                     lcd.printString("Ready.",20,1);
00807                     lcd.refresh();
00808                     wait(0.5);
00809                     lcd.printString("Ready..",20,1);
00810                     lcd.refresh();
00811                     wait(0.5);
00812                     lcd.printString("Ready...",20,1);
00813                     lcd.refresh();
00814                     wait(1);
00815                     lcd.printString("GO!",31,3);
00816                     lcd.refresh();
00817                     wait(1);
00818                     lcd.clear();
00819                     fsm_state  = 1; ///2 lives left
00820                 } else if (tries  == 1) {
00821                     
00822                     g_button1_flag  = 0;
00823                     lcd.clear();
00824                     lcd.printString("Last Chance!",10,2);
00825                     lcd.refresh();
00826                     wait(1);
00827                     fsm_state  = 2; //1 life left
00828                 } else if (tries  == 0) {
00829                     
00830                     g_button1_flag  = 0;
00831                     fsm_state  = 3;
00832                     led_output=fsm [fsm_state ];
00833                     lcd.clear();
00834                     lcd.printString("Game Over!",10,2);
00835                     timer.stop();
00836                     timer.reset();
00837                     lcd.refresh();
00838                     wait(2);
00839 
00840                     ticker.detach();
00841                     game_ticker.attach(&game_timer_isr,0.2); ///attach a slower ticker to save power while not playing
00842                     lcd.clear();
00843                     lcd.printString("Play again!",0,0);
00844                     lcd.drawCircle(70,4,2,1);
00845                     lcd.refresh();
00846                     g_button_flag  = 0;
00847 
00848                     while(1) {
00849                         if  (g_button1_flag ) { ///if button1 is pressed
00850 
00851                             g_button1_flag  = 0; ///reset button1 flag
00852                             level  = 0; ///reset parameters
00853                             tries  = 3;
00854                             fsm_state  = 0;
00855                             led_output=fsm [fsm_state ];
00856                             buzzer.write(0.0);
00857                             lcd.clear();
00858                             ///reset values
00859                             heroX = 0;
00860                             heroY = 0;
00861                             rectY  = 0;
00862                             circleX  = 0;
00863                             main(); ///call main
00864                         }
00865                         sleep();
00866                     }
00867 
00868                 }
00869                 heroX = 0;
00870                 heroY = 0;
00871                 rectY  = 0;
00872                 circleX  = 0;
00873                 led_output=fsm [fsm_state ];
00874                 buzzer.write(0.0);
00875             }
00876 
00877         }
00878     }
00879 }
00880 
00881 
00882 
00883 
00884 
00885