Final Submission. I have read and agreed with Statement of Academic Integrity.

Dependencies:   mbed

Revision:
8:dc7b09f23d75
Parent:
7:8e1111ab8a8c
Child:
9:b160a3de0d00
--- a/main.cpp	Fri Jun 05 16:32:56 2020 +0000
+++ b/main.cpp	Fri Jun 05 18:07:26 2020 +0000
@@ -1,27 +1,46 @@
 #include "mbed.h"
 #include "Gamepad.h"
 #include "N5110.h"
-#include "Levels.h"
 
 //Objects
 Gamepad pad;
 N5110 lcd;
-//initialise global variables to be used throughought the game
+//initialise global variables to be used throughout the game
+//initial player position in all levels.
 char player_char = 'x';
 int player_xpos = 8;
 int player_ypos = 45;
 
-int aim_xpos = 0;
-int aim_ypos = 0;
+int aim_xpos;
+int aim_ypos;
 
 int portal_1_xpos;
 int portal_1_ypos;
 
 int portal_2_xpos;
 int portal_2_ypos;
+
+//initialise x direction movement
+int move = 0;
+//initialise terminators for menu and game loops.
+bool choice = false;
+bool endgame = false;
+
 //initialise Game array
 char array[84][48];
-//Level 1. the 
+/*the characters in the level array's represent the following:
+'0' = air
+'1' = right facing wall
+'2' = floor
+'3' = cieling
+'4' = left facing wall
+'B' = Button
+'S' = Spikes
+'P' = portal 1
+'Q' = portal 2
+'x' = player
+*/
+// level 1
 char _level_1[84][48] = {
     {'3','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','2'},
     {'3','0','0','0','0','0','0','0','0','0','2','3','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','2'},
@@ -108,8 +127,8 @@
     {'3','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','2'},
     {'3','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','2'},
  }; 
- 
-char _level_2[84][48] = {
+ // level 3
+char _level_3[84][48] = {
     {'3','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','2'},
     {'3','0','0','0','2','2','0','0','0','0','0','0','0','2','3','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','2','3','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','2'},
     {'3','0','0','0','0','2','0','0','0','0','0','0','0','2','3','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','2','3','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','2'},
@@ -195,8 +214,8 @@
     {'3','0','0','0','0','0','0','2','3','0','0','0','0','0','0','0','0','0','0','0','0','2','1','1','1','1','1','1','1','1','2','3','0','0','0','0','0','0','0','D','0','0','0','0','0','0','0','2'},
     {'3','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','2'},
  };
- 
-char _level_3[84][48] = {
+ // level 2
+char _level_2[84][48] = {
     {'3','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','4','2'},
     {'3','0','0','0','2','2','0','0','0','0','0','0','0','2','3','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','2','0','0','0','0','0','2'},
     {'3','0','0','0','0','2','0','0','0','0','0','0','0','2','3','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','2','0','0','0','0','0','2'},
@@ -283,24 +302,11 @@
     {'3','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','2'},
  };  
 
-
-
-
-
-int move = 0;
-bool endgame = false;
-bool choice = false;
  
 //Prototypes
 void pad_init();
 void update_display();
-void draw_array();
-void player_object();
-void Copy_array();
-void player_movements();
-void update_array();
 void apply_move();
-void add_surface_array();
 void add_player_array();
 void get_move(int, Gamepad &pad);
 void print_screen();
@@ -313,17 +319,20 @@
 //Main function
 int main()
 {
-    
+//initialise the pad   
     pad_init();
+    //loop until player has selected an option from the menu
     while(choice == false) {
+        //print welcome screen
         lcd.clear();
         lcd.printString("Welcome to",0,0);
         lcd.printString("2D Portal!",0,1);
         lcd.printString("A = controls",0,2);
         lcd.printString("B = Level 1",0,3);
         lcd.printString("X = Level 2",0,4);
-        lcd.printString("y = Level 3",0,5);
+        lcd.printString("Y = Level 3",0,5);
         update_display();
+        //cycle LED's whilst on home screen
         pad.led(1,1);
         wait(0.05);
         pad.leds_off();
@@ -342,6 +351,7 @@
         pad.led(6,1);
         wait(0.05);
         pad.leds_off();
+        // print the controls for 5 seconds, then return to the menu screen.
         if(pad.A_pressed() == 1){
             lcd.clear();
             lcd.printString("Joystick =Move",0,0);
@@ -355,52 +365,70 @@
             wait_ms(5000);
             choice = false;
             }
+            //loads level 1.
         else if(pad.B_pressed() == 1){
             for(int i = 0; i < 84; i ++){
                 for(int j = 0; j < 48; j ++){
                     array[i][j] = _level_1[i][j];
                     choice = true;}}}
+            //loads level 2
         else if(pad.X_pressed() == 1){
             for(int i = 0; i < 84; i ++){
                 for(int j = 0; j < 48; j ++){
                     array[i][j] = _level_2[i][j];
                     choice = true;}}}
+            //loads level 3
         else if(pad.Y_pressed() == 1){
             for(int i = 0; i < 84; i ++){
                 for(int j = 0; j < 48; j ++){
                     array[i][j] = _level_3[i][j];
                     choice = true;}}}
+        //refresh lcd to display chosen level when menu loop breaks.
         lcd.refresh();
-        //Cycle through leds whilst on the home screen
     }
-    update_display();
-    //Loop runs forever
+    //Loop runs until the player has solved the puzzle and exited the right hand side of the screen.
     while(endgame == false){
+        // converts joystick input into left or right movement.
         get_move(move, pad);
+        
+        // checks to see if the move is valid and handles teleportation logic.
         collision_detection(move);
+        // checks to see if the player has jumped, if they have then the players y pos will descrease by 1
         if(pad.A_pressed() == 1){
             jump();
             }
+        //checks to see if the player has placed portal 1, if they have then the portal will be placed in the array
         else if(pad.B_pressed() == 1){
             place_portal_1();
+            //turns on left red led to show portal 1 has been placed.
+            pad.led(1,1);
             }
-
+        //checks to see if the player has placed portal 2, if they have then the portal will be placed in the array
         else if(pad.Y_pressed() == 1){
             place_portal_2();
+            //turns on right red led to show portal 2 has been placed.
+            pad.led(4,1);
             }
         else
+        //handles setting the new position of the player in the array and erasing the previous player position from the array.
         apply_move();
-        add_player_array();
+        //prints to the lcd
         print_screen();
+        //refreshes the lcd to display the new screen after movement.
         update_display();
+        // the objective of the game is to open the door and walk through it. as the door is on the right hand side of the screen, when the player
+        // xpos exceeds 82, the puzzle is assumed to be solved as the door has to be opened to progress.
         if(player_xpos > 82){
             endgame = true;}
     }
+    //clear the level and print the win screen
     lcd.clear();
-    lcd.printString("puzzle solved",0,0);
+    lcd.printString("Puzzle solved!",0,0);
+    lcd.printString("Press reset",0,0);
+    lcd.printString("To play again",0,0);
     lcd.refresh();
 }
-
+//initialise the game array with 0's
 void array_init(){
     for(int j = 0; j < 48; j++){
         for(int i = 0; i < 84; i++){
@@ -408,16 +436,17 @@
          }}}    
 
 void apply_move(){
-    
+    // removes old player char in the array and increments the value of the player_xpos by the value in move
     int old_player_xpos = player_xpos;
     player_xpos += move;
     array[old_player_xpos][player_ypos] = '0';
-    
+    //checks if the player is in the air, if they are then increase y by 1 until the player is on the floor and remove the old player char from the array
     int old_player_ypos = player_ypos;
     if(array[player_xpos][player_ypos+1] == '0'){
         player_ypos += 1;
         array[player_xpos][old_player_ypos] = '0';
         }
+    //checks if the player has landed on spikes and displays the end game screen with instructions for how to restart the game if they have.
     else if(array[player_xpos][player_ypos+1] == 'S'){
         lcd.clear();
         lcd.printString("Spike hit!",0,0);
@@ -425,11 +454,14 @@
         lcd.printString("Try again!",0,2);
         lcd.refresh();
         wait_ms(1000000000);
+    //places the player char in the array
+    add_player_array();
         
         }
 }
     
-
+// converts the chars in the array to on or off pixels, dependant on the type of object in the array. i.e walls are a dark pixel and portals are a light pixel
+// this helps to distinguis where the portals are.
 void print_screen(){
  for(int j = 0; j < 48; j++){
     for(int i = 0; i < 84; i++){
@@ -456,8 +488,9 @@
              lcd.setPixel(i,j, true);
             }
             }}
-            
+         // finds the position pot(2) is aiming at and prints the aim assist line   
          get_portal_angle();
+         // prints the player sprite
          lcd.setPixel(player_xpos,player_ypos-1, true);
          lcd.setPixel(player_xpos-1,player_ypos-2, true);
          lcd.setPixel(player_xpos-1,player_ypos-3, true);
@@ -471,82 +504,91 @@
  
  
 
-//Prototype functions
-void pad_init(){   
+//initilise the pad and LCD
+void pad_init()
+{   
     lcd.init();
     lcd.setContrast(0.45);
     lcd.clear();
     pad.init();
 }
-
+//places the player char in the array
 void add_player_array()
 {
      array[player_xpos][player_ypos] = player_char;
 }
 
 
-
+// takes the input from the joystick and converts it into left/rigth movments
 void get_move(int, Gamepad &pad)
 {
 char d = pad.get_direction();
 
         if(d == E){
             move = 1;
-            
             }
         else if(d == W){
-            move = -1;
-        
-            
+            move = -1;   
     }
     else move = 0;
     }
 
 
-    
+// refreshes the display with the updated game screen    
 void update_display()
 {
     lcd.refresh(); //Refreshes the lcd so the pixels appear
     wait_ms(150);  //Frame rate of game
 }
 
-/////////////////////////////// all of above is the main loop and a little bit of player stuff. 
-
 void collision_detection(int)
 {
+    //check if the player is moving into any object other than air. if they are then x direction movement = 0
     char dir = pad.get_direction();
     if(array[player_xpos+1][player_ypos] != '0' && dir == E){
         move = 0;}
     else if(array[player_xpos-1][player_ypos] != '0' && dir == W){
         move = 0;}
+    // checks if the player is directly next to a portal and runs the logic to check where the player should be teleported to. This is dependant on the surfaces the second portal is placed on.
     if(array[player_xpos+1][player_ypos] == 'P' || array[player_xpos-1][player_ypos] == 'P' || array[player_xpos][player_ypos-1] == 'P'  || array[player_xpos][player_ypos+1] == 'P' ){
         move = 0;
+    // removes the old player char from the array
         array[player_xpos][player_ypos] = '0';
+    //logic for entering portal 1
+        // if the position horizontally next to portal 2 is a '3' then portal 2 has been placed on a ceiling and the player must be placed below portal 2.
         if (array[portal_2_xpos-1][portal_2_ypos] == '3'){
             player_xpos = portal_2_xpos;
             player_ypos = portal_2_ypos+2;}
+        // if the position horizontally next to portal 2 is a '2' then portal 2 has been placed on a floor and the player must be placed above and to the side of portal 2 so they dont fall back in.
         else if(array[portal_2_xpos-1][portal_2_ypos] == '2'){
                 player_xpos = portal_2_xpos + 1;
                 player_ypos = portal_2_ypos-1;}
+        // if the position vertically next to portal 2 is a '1' then portal 2 has been placed on a right facing wall and the player must be placed on the left of portal 2.
         else if(array[portal_2_xpos][portal_2_ypos - 1] == '1'){
                 player_xpos = portal_2_xpos - 2;
                 player_ypos = portal_2_ypos;}
+        // if the position vertically next to portal 2 is a '4' then portal 2 has been placed on a left facing wall and the player must be placed on the right of portal 2.
         else if(array[portal_2_xpos][portal_2_ypos - 1] == '4'){
                 player_xpos = portal_2_xpos + 2;
                 player_ypos = portal_2_ypos;}
                 }
+    // logic for entering portal 2
     else if(array[player_xpos+1][player_ypos] == 'Q' || array[player_xpos-1][player_ypos] == 'Q' || array[player_xpos][player_ypos-1] == 'Q'  || array[player_xpos][player_ypos+1] == 'Q' ){
         move = 0;
         array[player_xpos][player_ypos] = '0';
+        // if the position horizontally next to portal 1 is a '3' then portal 1 has been placed on a ceiling and the player must be placed below portal 1.
         if (array[portal_1_xpos-1][portal_1_ypos] == '3'){
             player_xpos = portal_1_xpos;
             player_ypos = portal_1_ypos+2;}
+        // if the position horizontally next to portal 1 is a '2' then portal 1 has been placed on a floor and the player must be placed above and to the side of portal 1 so they dont fall back in.
         else if(array[portal_1_xpos-1][portal_1_ypos] == '2'){
                 player_xpos = portal_1_xpos + 1;
                 player_ypos = portal_1_ypos-1;}
+        // if the position vertically next to portal 1 is a '1' then portal 1 has been placed on a right facing wall and the player must be placed on the left of portal 1.
         else if(array[portal_1_xpos][portal_1_ypos - 1] == '1'){
                 player_xpos = portal_1_xpos - 2;
                 player_ypos = portal_1_ypos;}
+        // if the position vertically next to portal 1 is a '4' then portal 1 has been placed on a left facing wall and the player must be placed on the right of portal 1.
         else if(array[portal_1_xpos][portal_1_ypos - 1] == '4'){
                 player_xpos = portal_1_xpos + 2;
                 player_ypos = portal_1_ypos;}
@@ -556,17 +598,16 @@
         
         
         
-        
+    //removes the old player char from the array and replaces it with zero  
     erase_old_sprites(player_xpos, player_ypos);
+    //checks if the player has stepped on the button, if they have then the button and door are replaced by air and the route to the exit is open.  
     if(array[player_xpos][player_ypos+1] == 'B'){
         for(int i = 0; i < 84; i++){
             for(int j = 0; j < 48; j++){
                 if(array[i][j] == 'D' || array[i][j] == 'B'){
                     array[i][j] = '0';}}}}
-    
-    else{ move = move;}
 }
-
+// removes the old player character from the array.
 void erase_old_sprites(char,char)
 {
     int old_player_xpos = player_xpos;
@@ -576,88 +617,116 @@
     array[player_xpos][old_player_ypos] = '0';
     }
     
-    
+
 void jump()
-{
+{       //if the space beneath the player = floor, then increase ypos by 1. Apply move causes the player to fall again shortly after on the next loop.
         if(array[player_xpos][player_ypos+1] == '2'){
         int old_player_ypos = player_ypos;
         player_ypos += -1;
+        //removes old player char from the array
         array[player_xpos][old_player_ypos] = '0';
         }
 }        
 
-
-//////////////////code so far has movement, surface and portal detection and relevant behaviours.
 // next steps are to turn pot into degrees and make a function which chechks which pixel the pot is pointing at. 
-
+// this function takes the pot(2) input range and converts it into 45 degree segments, after which the aim detector is sent out until it hits another object
 void get_portal_angle()
 {
+    //take pot(2) val as a double to allow for more precise segments.
     double angle_input = pad.read_pot2();
-    float gradient = tan(angle_input*360);
+    
+    //position the player is aiming at
     aim_xpos = player_xpos;
     aim_ypos = player_ypos;
+    
+    // if pot(2) is between 0 and 45 degrees, aim detection is projected at the floor, 
     if(angle_input > 0 && angle_input < 0.125){
+        // The aim_ypos will increment until it is next to a surface that isnt the air.
         while(array[aim_xpos][aim_ypos + 1] == '0'){
         aim_ypos = player_ypos + 1;
         }
+        // increment once more to place portal in the surface
         aim_ypos = player_ypos + 1;
+        }
         
-        }
+    // if pot(2) is between 45 and 90 degrees, aim detection is diagonally down left
     else if(angle_input > 0.125 && angle_input < 0.25){
         while(array[aim_xpos -1 ][aim_ypos + 1] == '0'){
+        // performs relevant increments and decrements for downward diagonal left movement. 
         aim_xpos += - 1;
         aim_ypos += 1;
         }
+        // performs increments and decrements once more to place portal in the surface
         aim_xpos += - 1;
         aim_ypos += 1;
         }
+    // if pot(2) is between 90 and 135 degrees, aim detection is projected towards the left
     else if(angle_input > 0.25 && angle_input < 0.375){
         while(array[aim_xpos -1 ][aim_ypos] == '0'){
+        // The aim_xpos will decrement until it is next to a surface that isnt the air.
         aim_xpos += - 1;
         }
+        // decrement once more to place portal in the surface
         aim_xpos += - 1;
         }
+    // if pot(2) is between 135 and 180 degrees, aim detection is diagonally up left
     else if(angle_input > 0.375 && angle_input < 0.5){
         while(array[aim_xpos -1 ][aim_ypos-1] == '0'){
+        // performs relevant decrements for upward diagonal left movement. 
         aim_xpos += - 1;
         aim_ypos += - 1;
         }
+        // performs decrements once more to place portal in the surface
         aim_xpos += - 1;
         aim_ypos += -1;
         }
+    // if pot(2) is between 180 and 225 degrees, aim detection is upwards
     else if(angle_input > 0.5 && angle_input < 0.625){
         while(array[aim_xpos][aim_ypos-1] == '0'){
+        // The aim_ypos will decrement until it is next to a surface that isnt the air.
         aim_ypos += - 1;
         }
+        // decrement once more to place portal in the surface
         aim_ypos += -1;
         }
+    // if pot(2) is between 225 and 270 degrees, aim detection is diagonally up right
     else if(angle_input > 0.625 && angle_input < 0.75){
         while(array[aim_xpos+1][aim_ypos-1] == '0'){
+        // performs relevant increments and decrements for downward diagonal left movement.
         aim_ypos += - 1;
         aim_xpos += 1;
         }
+        // performs increments and decrements once more to place portal in the surface.
         aim_ypos += -1;
         aim_xpos +=  1;
         }
+    // if pot(2) is between 270 and 315 degrees, aim detection is to the right
     else if(angle_input > 0.75 && angle_input < 0.875){
         while(array[aim_xpos+1][aim_ypos] == '0'){
+        // The aim_xpos will increment until it is next to a surface that isnt the air.
         aim_xpos += 1;
         }
+        // The aim_xpos will increment once more to place the portal in the surface.
         aim_xpos +=  1;
         }
+    // if pot(2) is between 315 and 360 degrees, aim detection is diagonally down right
     else if(angle_input > 0.875 && angle_input < 1){
         while(array[aim_xpos+1][aim_ypos + 1] == '0'){
+        // performs relevant increments for downward diagonal left movement.
         aim_xpos += 1;
         aim_ypos += 1;
         }
+        // performs increments once more to place portal in the surface
         aim_xpos +=  1;
         aim_ypos += 1;
         }
+    // draw the aim assist dashed line to give a visual representation of where the player is aiming the portal gun
+    // this code allows for dynamic drawing of the aim assist relevant to the players position and the aim direction given by the potentiometer
     lcd.drawLine((player_xpos),(player_ypos), aim_xpos,aim_ypos,2);
     lcd.refresh();
     }
     
-    
+//removed the old portal 1 and places the new one where the aim assist is pointed.    
 void place_portal_1()
 {
         int old_p1_xpos = portal_1_xpos;
@@ -667,7 +736,7 @@
         portal_1_ypos = aim_ypos;
         array[portal_1_xpos][portal_1_ypos] = 'P';}        
         
-
+//removed the old portal 2 and places the new one where the aim assist is pointed.  
 void place_portal_2()
 {
         int old_p2_xpos = portal_2_xpos;