Joe Shotton / Mbed 2 deprecated ELEC2645_Project_ll16j23s

Dependencies:   mbed ll16j23s_test_docs

Revision:
10:a2d643b3c782
Parent:
9:0571880085cc
--- a/SnakeEngine/SnakeEngine.cpp	Mon May 25 20:31:52 2020 +0000
+++ b/SnakeEngine/SnakeEngine.cpp	Tue May 26 23:25:09 2020 +0000
@@ -2,12 +2,11 @@
 
 SnakeEngine::SnakeEngine() {
     //constructor
-    score = 0;
     _menu_select = 0;
     _map_select = 0;
-    _game_state = 1;
     _pot2 = 0.5;
     _death = false;
+    score = 0;
 
 }
 
@@ -17,48 +16,49 @@
 }
  
 void SnakeEngine::game_init(Gamepad &pad, N5110 &lcd, FXOS8700CQ &mag){
-    transition_black(lcd);
+    game_reset(); //resets game
+    transition_black(lcd); //transition animations
     transition_white(lcd);
-    map_run(lcd);
-    _food.init(mag);
-    _body.init();
-    _food.rand_pos(pad, lcd);
-    menu_flash(pad, 3);
+    map_run(lcd); //displays map
+    lcd.refresh();
+    _food.init(pad, lcd, mag); //initialises food (including new seed for random function
+    _body.init();   //initialises body
+    menu_flash(pad, 3); //flashes LEDs
+    game_state = 3;     //sets game_state to the game itself, which changes the active while loop in main.cpp
 } 
 
 
 void SnakeEngine::game_run(Gamepad &pad, N5110 &lcd){
-    //input???
-    map_run(lcd);
-    _body.run(pad, lcd, _death);
-    _food.run(lcd);
-    snake_food_collision(pad, lcd, _body._length);  
-    if (_death == true) {
-        printf("Dead!");
-        _game_state = 4;   
-        death_init(pad, lcd);
+    map_run(lcd); //displays the map and calculates relevant map collisions
+    _body.run(pad, lcd, _death);    
+    _food.run(lcd);   
+    snake_food_collision(pad, lcd);
+    if (_death == true) {       //checks death (either snake-snake collision or snake-wall-collision)
+        //printf("Dead!");        
+        game_state = 4;         //sets game_state to death, which changes the active while loop in main.cpp
+        death_init(pad, lcd);   //displays death menu
     }
     //snake-wall collision 
 } 
 
-void SnakeEngine::snake_food_collision(Gamepad &pad, N5110 &lcd, int &_length) {
-    if (_food._x == _body._x_head && _food._y == _body._y_head){
+void SnakeEngine::snake_food_collision(Gamepad &pad, N5110 &lcd) {
+    if (_food._x == _body._x_head && _food._y == _body._y_head){ //if coords of food and head match
         //printf("FOOD!");
-        pad.led(3,0.9);
+        pad.led(3,0.9); //turns on green LEDs
         pad.led(6,0.9);
-        while (_food.rand_pos(pad, lcd) == false){
-            _food.rand_pos(pad, lcd);
-            printf("Reselected food position\n");
+        while (_food.rand_pos(pad, lcd) == false){  //while new food coordinates are in the snake/walls
+            _food.rand_pos(pad, lcd);               //choose new coords by rerunning the function
+            //printf("Reselected food position\n");
         }
-        _body.add_length(5);
-        score++;
-        pad.led(3,0.0);
+        _body.add_length(5); //sets length increase
+        score++;             
+        pad.led(3,0.0);      //turns off green LEDs
         pad.led(6,0.0);
     }
 }
 
 void SnakeEngine::map_run(N5110 &lcd) {
-    switch(_map_select+1) {
+    switch(_map_select+1) { //selects chosen map
         case 2:
             map2_draw(lcd);
             snake_map2_collision();    
@@ -74,13 +74,13 @@
     }
 }
 
-void SnakeEngine::snake_map2_collision() {
+void SnakeEngine::snake_map2_collision() { //ring map
     if (_body._x_head < 2 || _body._x_head > 81 || _body._y_head < 2 || _body._y_head > 45){ //if snakehead coords exceed the ring coords
         _death = true; 
     }
 }
 
-void SnakeEngine::snake_map3_collision() {
+void SnakeEngine::snake_map3_collision() { //cross map
     if ((_body._x_head == 40 || _body._x_head == 42) && (_body._y_head < 16 || _body._y_head > 30)){ 
     //if head is at the either of the N/S walls' x coords, and above (y=18) or below (y=30), trigger death 
         _death = true; 
@@ -90,215 +90,211 @@
     }
 }
 
-void SnakeEngine::snake_map4_collision() {
-    /*
-    for(int i = 0; i < 48; i++){
-        if(_body._x_head == MAP 4 COORDS && _body._y_head == MAP 4 COORDS) {
-            return true;
-            } 
-    */
-}
-
-void SnakeEngine::map2_draw(N5110 &lcd){
-       lcd.drawRect(0, 0, 84, 48,FILL_TRANSPARENT);
-       lcd.drawRect(1, 1, 82, 46,FILL_TRANSPARENT);
+void SnakeEngine::snake_map4_collision() { //lanes
+    _map4_location = 0;
+    if (_body._x_head == 8 || _body._x_head == 10 || _body._x_head == 40 || _body._x_head == 42 || _body._x_head == 72 || _body._x_head == 74){
+         _map4_location += 1; //adjust tracker if x matches upper/lower walls
+    } //printf("x matches upper/lower walls");
+    if (_body._y_head < 12 || _body._y_head > 34){
+         _map4_location += 3; //adjust tracker if y matches upper/lower walls
+    } //printf("y matches upper/lower walls");
+    if (_body._x_head == 24 || _body._x_head == 26 || _body._x_head == 56 || _body._x_head == 58){
+         _map4_location += 2; //adjust tracker if x matches mid walls
+    } //printf("x matches mid walls");
+    if (_body._y_head > 14 && _body._y_head < 32){
+         _map4_location += 2; //adjust tracker if y matches mid walls
+    } //printf("y matches mid walls");
+    if (_map4_location == 4){ //tracker will only be 4 if the correct combination of arguments is triggered - ie 1+3 (upper/lower walls) or 2+2 (mid walls)   
+    _death = true; 
+    } //printf("Wall collision");
 }
 
-void SnakeEngine::map3_draw(N5110 &lcd){
-        lcd.drawRect(40, 0, 4, 16,FILL_BLACK); //N wall
-        lcd.drawRect(68, 22, 16, 4,FILL_BLACK);//E wall
-        lcd.drawRect(40, 32, 4, 16,FILL_BLACK);//S wall
-        lcd.drawRect(0, 22, 16, 4,FILL_BLACK); //W wall
+void SnakeEngine::map2_draw(N5110 &lcd){ //rings
+    lcd.drawRect(0, 0, 84, 48,FILL_TRANSPARENT); //outer pixels of ring
+    lcd.drawRect(1, 1, 82, 46,FILL_TRANSPARENT); //inner pixels
+}
+
+void SnakeEngine::map3_draw(N5110 &lcd){ //cross
+    lcd.drawRect(40, 0, 4, 16,FILL_BLACK); //N wall
+    lcd.drawRect(68, 22, 16, 4,FILL_BLACK);//E wall
+    lcd.drawRect(40, 32, 4, 16,FILL_BLACK);//S wall
+    lcd.drawRect(0, 22, 16, 4,FILL_BLACK); //W wall
 }
 
-void SnakeEngine::map4_draw(N5110 &lcd){
-        lcd.drawRect(12, 8, 4, 4,FILL_BLACK); //NW square
-        lcd.drawRect(12, 36, 4, 4,FILL_BLACK);//SW square
-        lcd.drawRect(68, 8, 4, 4,FILL_BLACK); //NE square
-        lcd.drawRect(68, 36, 4, 4,FILL_BLACK);//SE square
-        
-        lcd.drawRect(38, 6, 8, 8,FILL_BLACK); //N large square
-        lcd.drawRect(24, 20, 8, 8,FILL_BLACK);//E large square
-        lcd.drawRect(38, 34, 8, 8,FILL_BLACK);//S large square
-        lcd.drawRect(52, 20, 8, 8,FILL_BLACK);//W large square
+void SnakeEngine::map4_draw(N5110 &lcd){ //lanes   
+    lcd.drawRect(8, 0,  4, 12,FILL_BLACK);//NW line
+    lcd.drawRect(8, 36, 4, 12,FILL_BLACK);//SW line    
+    lcd.drawRect(40, 0,  4, 12,FILL_BLACK);//N-mid line
+    lcd.drawRect(40, 36, 4, 12,FILL_BLACK);//S-mid line
+    lcd.drawRect(72, 0,  4, 12,FILL_BLACK);//NE line
+    lcd.drawRect(72, 36, 4, 12,FILL_BLACK);//SE line 
+    lcd.drawRect(24, 16, 4, 16,FILL_BLACK);//mid-W line
+    lcd.drawRect(56, 16, 4, 16,FILL_BLACK);//mid-E line
 }
 
-
 void SnakeEngine::transition_black(N5110 &lcd) {
-    //lcd.clear();
     for (int j = 0; j < 21; j += 4) {   //j iterator controls the size and location of current loop
         //printf("j: %d\n", j); 
         for (int i = 1; i < 84 - (2*j); i += 2) { //i iterator controls length of rectangles
-            lcd.drawRect(j, j, i + 1, 4, FILL_BLACK); //top horizontal rectangle              
-            lcd.drawRect(83 - j - i, 44 - j, i + 1, 4, FILL_BLACK);  //bottom horizontal rectangle
+            lcd.drawRect(j, j, 1 + i, 4, FILL_BLACK); //top horizontal rectangle grows to the right by adding i iterator to width              
+            lcd.drawRect(83 - j - i, 44 - j, 1 + i, 4, FILL_BLACK);  //bottom horizontal rectangle grows to the left by subtracting i iterator from x position,
+            //and adding i iterator to width
             wait_ms(5);   
-            lcd.refresh(); //refreshes screen without clearing it to maintain previous loops
+            lcd.refresh(); //refreshes screen without clearing it to maintain previous loops' rectangles
         }
         for (int i = 1; i < 43 - (2*j); i += 2) { //i iterator controls length of rectangles
-            lcd.drawRect(80 - j, 4 + j, 4, i,FILL_BLACK); //right vertical rectangle    
-            lcd.drawRect(j, 44 - i - j, 4, i,FILL_BLACK); //left vertical rectangle    
+            lcd.drawRect(80 - j, 4 + j, 4, i,FILL_BLACK); //right vertical rectangle grows down by adding i iterator to height    
+            lcd.drawRect(j, 44 - j - i, 4, i,FILL_BLACK); //left vertical rectangle grows up by subtracting i iterator from y position, adds i to height   
             wait_ms(5);   
             lcd.refresh(); //refreshes screen without clearing it to maintain previous loops
         }
     }
-    //wait_ms(500);      
 }
 
 void SnakeEngine::transition_white(N5110 &lcd) {
-    //lcd.clear();
-    for (int j = 0; j < 21; j += 4) {
-        //printf("j: %d\n", j);
-        for (int i = 1; i < 84 - (2*j); i += 2) {
-            lcd.drawRect(j, j, i + 1, 4, FILL_WHITE);
-            lcd.drawRect(83 - j - i, 44 - j, i + 1, 4, FILL_WHITE);  
+    //functionally same as black transition function
+    for (int j = 0; j < 21; j += 4) {   //j iterator controls the size and location of current loop
+        //printf("j: %d\n", j); 
+        for (int i = 1; i < 84 - (2*j); i += 2) { //i iterator controls length of rectangles
+            lcd.drawRect(j, j, 1 + i, 4, FILL_WHITE); //top horizontal rectangle grows to the right by adding i iterator to width              
+            lcd.drawRect(83 - j - i, 44 - j, 1 + i, 4, FILL_WHITE);  //bottom horizontal rectangle grows to the left by subtracting i iterator from x position,
+            //and adding i iterator to width
             wait_ms(5);   
-            lcd.refresh();
+            lcd.refresh(); //refreshes screen without clearing it to maintain previous loops' rectangles
         }
-        for (int i = 1; i < 43 - (2*j); i += 2) {
-            lcd.drawRect(80 - j, 4 + j, 4, i,FILL_WHITE);
-            lcd.drawRect(j, 44 - i - j, 4, i,FILL_WHITE); 
+        for (int i = 1; i < 43 - (2*j); i += 2) { //i iterator controls length of rectangles
+            lcd.drawRect(80 - j, 4 + j, 4, i,FILL_WHITE); //right vertical rectangle grows down by adding i iterator to height    
+            lcd.drawRect(j, 44 - j - i, 4, i,FILL_WHITE); //left vertical rectangle grows up by subtracting i iterator from y position, adds i to height   
             wait_ms(5);   
-            lcd.refresh();
+            lcd.refresh(); //refreshes screen without clearing it to maintain previous loops
         }
     }
-    //wait_ms(500);      
 }
 
 void SnakeEngine::menu1_init(Gamepad &pad, N5110 &lcd){
-         contrast(pad, lcd);
-         transition_black(lcd);
+         contrast(pad, lcd); //adjusts contrast before transitions
+         transition_black(lcd); 
          transition_white(lcd);
-         lcd.clear();
          lcd.refresh();
          //printf("Menu 2\n");
-         lcd.printString("    SNAKE",3,0);
+         lcd.printString("SNAKE",27,0); //displays relevant text
          lcd.printString("Play",30,2);
-         lcd.drawCircle(24,19,3,FILL_TRANSPARENT);
+         lcd.drawCircle(24,19,3,FILL_TRANSPARENT); //draws empty circles for option display 
          lcd.printString("Maps",30,3);
          lcd.drawCircle(24,27,3,FILL_TRANSPARENT);
          lcd.refresh();   
-         menu_flash(pad, 2);
+         menu_flash(pad, 2); //flashes orange LEDs
 }
 
-void SnakeEngine::menu1_select(N5110 &lcd, Gamepad &pad, FXOS8700CQ &mag){    
+void SnakeEngine::menu1_select(Gamepad &pad, N5110 &lcd, FXOS8700CQ &mag){    
     //printf("Menu 1\n");
-    if (pad.X_pressed() == true){ //detect if 'up' selection
-        _menu_select--;
-    } else if (pad.B_pressed() == true){ //detect if 'down' selection
+    if (pad.X_held() == true){ //detect if 'up' selection
+        _menu_select--; 
+    } else if (pad.B_held() == true){ //detect if 'down' selection
         _menu_select++;
     }
-    _menu_select = ((_menu_select % 2) + 2) % 2; //wrap around numbers, ie down on 2 goes to 1 and up on 1 goes to 2
+    _menu_select = ((_menu_select % 2) + 2) % 2; //wrap around numbers, ie down on 1 goes to 0 and up on 0 goes to 1
     select_circles(lcd, _menu_select + 1); //draw black circle in selected option
     //printf("Option: %d\n", _menu_select + 1);
     
-    if (pad.A_pressed() == true){ //if option 1 selected and 'A' pressed
+    if (pad.A_held() == true){ //if option 1 selected and 'A' held
         if (_menu_select == 0){
             game_init(pad, lcd, mag);      //Initialise game
-            _game_state = 3;    //switch state
-        } else {
+        } else {   //otherwise must be option 2
             menu2_init(pad, lcd);    //Initialise menu 2
-            _game_state = 2;    //switch state
+            menu_flash(pad, 2); //flashes orange LEDs
         }
     }
 }
 
 void SnakeEngine::menu2_init(Gamepad &pad, N5110 &lcd){
-         //transition_black(lcd);
-         //transition_white(lcd);
-         //printf("Menu 1\n");
+         //printf("Menu 2\n");
          lcd.clear();   
-         lcd.printString("     MAPS",0,0);
+         lcd.printString("     MAPS",0,0);          //displays relevant text
          lcd.printString("Empty",30,2);
-         lcd.drawCircle(24,19,3,FILL_TRANSPARENT);
+         lcd.drawCircle(24,19,3,FILL_TRANSPARENT); //draws empty circles for option display 
          lcd.printString("Ring",30,3);
          lcd.drawCircle(24,27,3,FILL_TRANSPARENT);
          lcd.printString("Cross",30,4);
          lcd.drawCircle(24,35,3,FILL_TRANSPARENT);
-         lcd.printString("Spots",30,5);
+         lcd.printString("Lanes",30,5);
          lcd.drawCircle(24,43,3,FILL_TRANSPARENT);
          lcd.refresh();   
-         menu_flash(pad, 2);
+         game_state = 2;  //sets game_state to menu 2, which changes the active while loop in main.cpp
 }
 
-void SnakeEngine::menu2_select(N5110 &lcd, Gamepad &pad){   
+void SnakeEngine::menu2_select(Gamepad &pad, N5110 &lcd, FXOS8700CQ &mag){   
+    
+    select_circles(lcd, _map_select+1);
     
     //printf("Menu 2\n");
-    if (pad.X_pressed() == true){
+    if (pad.X_held() == true){
         _map_select--;
-    } else if (pad.B_pressed() == true){
-        _map_select++;
-    } else if (pad.Y_pressed() == true){
-        preview(pad, lcd, _map_select+1);
-    } else if (pad.A_pressed() == true){
-        //game_init();
-        _game_state = 3;
+    } else if (pad.B_held() == true){
+        _map_select++; 
+    } else if (pad.Y_held() == true){
+        preview(pad, lcd); //allows short preview of map to be displayed
+    } else if (pad.A_held() == true){
+        game_init(pad, lcd, mag); //intialises game
     }
-    
     //printf("Map: %d\n", _map_select);
-    _map_select = ((_map_select % 4) + 4) % 4;
-    select_circles(lcd, _map_select+1);
+    _map_select = ((_map_select % 4) + 4) % 4; //wrap around numbers, ie down on 3 goes to 0 and up on 0 goes to 3 
 }
 
 
 void SnakeEngine::death_init(Gamepad &pad, N5110 &lcd){
-         _death = 0;
-         _menu_select = 0;
+         _death = 0;         //resets death flag
+         _menu_select = 0;   //resets menu select so 'play again' is default   
          transition_black(lcd);
          transition_white(lcd);
          //printf("Game over\n");
-         lcd.printString("  GAME OVER",3,0);
+         lcd.printString("  GAME OVER",3,0); //displays relevant text
          lcd.printString("    Score:",0,1);
-         char buffer[14];
+         char buffer[14];                    //creates a buffer for the score
          sprintf(buffer,"      %2d",score);   
          lcd.printString(buffer,0,2);
          lcd.printString("Again!",30,4);
-         lcd.drawCircle(24,35,3,FILL_TRANSPARENT);
+         lcd.drawCircle(24,35,3,FILL_TRANSPARENT); //draws empty circles for option selection
          lcd.printString("Maps",30,5);
          lcd.drawCircle(24,43,3,FILL_TRANSPARENT);
          lcd.refresh();
-         menu_flash(pad, 1);   
+         menu_flash(pad, 1);   //flashes red LEDs
 } 
 
-void SnakeEngine::death_select(N5110 &lcd, Gamepad &pad, FXOS8700CQ &mag){
+void SnakeEngine::death_select(Gamepad &pad, N5110 &lcd, FXOS8700CQ &mag){
     //printf("Menu 1\n");
-    if (pad.X_pressed() == true){ //detect if 'up' selection
+    if (pad.X_held() == true){ //detect if 'up' selection
         _menu_select--;
-    } else if (pad.B_pressed() == true){ //detect if 'down' selection
+    } else if (pad.B_held() == true){ //detect if 'down' selection
         _menu_select++;
     }
     _menu_select = ((_menu_select % 2) + 2) % 2; //wrap around numbers, ie down on 2 goes to 1 and up on 1 goes to 2
     select_circles(lcd, _menu_select + 3); //draw black circle in selected option
     //printf("Option: %d\n", _menu_select + 1);
     
-    if (pad.A_pressed() == true){ //if option 1 selected and 'A' pressed
+    if (pad.A_held() == true){ //if option 1 selected and 'A' held
         if (_menu_select == 0){
-            game_init(pad, lcd, mag); //Initialise game
-            _game_state = 3;    //switch state
+            game_init(pad, lcd, mag); 
+            game_state = 3;   
         } else {
-            menu2_init(pad, lcd);    //Initialise menu 2
-            _game_state = 2;    //switch state
+            menu2_init(pad, lcd);    
+            game_state = 2;    
         }
     }
 }  
 
 void SnakeEngine::select_circles(N5110 &lcd, int line) {
-    for(int i = 19; i < 52; i +=8) {
-        lcd.drawCircle(24,i,2,FILL_WHITE);
+    for(int i = 19; i < 52; i += 8) { //iterates over all the circle options' y values 
+        lcd.drawCircle(24,i,2,FILL_WHITE); //remove previous options' black circles
     }       
-    lcd.drawCircle(24,11+line*8,2,FILL_BLACK);
+    lcd.drawCircle(24, 11 + line * 8, 2, FILL_BLACK); //draws black circle in relevant option's blank circle 
     lcd.refresh();
     wait_ms(200);
-    //snake_select1.render(lcd, 0, 8);
-    //wait_ms(200);
-    //snake_select2.render(lcd, 0, 8);
-    //wait_ms(200);
-    //snake_select3.render(lcd, 0, 8);
-    //wait_ms(200);
 }
 
-void SnakeEngine::preview(Gamepad &pad, N5110 &lcd, int _map_select){
+void SnakeEngine::preview(Gamepad &pad, N5110 &lcd){
     lcd.clear(); 
-    switch(_map_select) {
+    switch(_map_select + 1) { //selects relevant map
         case 1:
             lcd.clear(); 
             lcd.printString("(Empty)",21,2);
@@ -316,22 +312,32 @@
             //lcd.printString("Spots",27,2);
             break;
         }
-    lcd.refresh(); 
-    wait_ms(1000);
+    lcd.refresh();
+    pad.led(2, 1);
+    pad.led(5, 1);
+    wait_ms(1000); //displays for 1 second
+    pad.led(2, 0);
+    pad.led(5, 0);
     lcd.clear();
-    menu2_init(pad, lcd);
+    menu2_init(pad, lcd); //re-initialises menu 2
 }
 
 void SnakeEngine::contrast(Gamepad &pad, N5110 &lcd){
     _pot2 = pad.read_pot2();
-    lcd.setContrast(0.25 + _pot2 * 0.5); 
+    lcd.setContrast(0.25 + _pot2 * 0.5); //maps pot value to range 0.25 - 0.75
     //printf("Contrast: %f\n", 0.25 + _pot2 * 0.5);  
 }
 
 void SnakeEngine::menu_flash(Gamepad &pad, int led){
     for(int i = 1; i < 7; i++){
-        pad.led(led, i % 2);  
-        pad.led(led + 3, i % 2);    
+        pad.led(led, i % 2); //flash left side LEDs - odd numbers become 1 to turn on, even numbers become 0 to turn off  
+        pad.led(led + 3, i % 2); //flash right side LEDs    
         wait_ms(100);
     }   
-}
\ No newline at end of file
+}
+
+void SnakeEngine::game_reset(){
+    score = 0;
+    _body.reset();
+}
+