This program runs through one level of Pacman. Be advised. This game is not fully functional. The ghost character was commented out due to its seeming inability to coexist with the Pacman character using my current code.

Dependencies:   4DGL-uLCD-SE mbed-rtos mbed

Files at this revision

API Documentation at this revision

Comitter:
srigdon3
Date:
Tue Mar 25 18:49:05 2014 +0000
Parent:
0:0a900ff9a788
Commit message:
This program runs through one level of Pacman. Be advised the game is not fully functional. The ghost character was commented out due to the game freezing with multiple characters present.

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Tue Mar 25 04:36:32 2014 +0000
+++ b/main.cpp	Tue Mar 25 18:49:05 2014 +0000
@@ -1,29 +1,35 @@
+/*
+So far, this program will run through one level of what will hopefully be a full Pacman game.
+As of now, only Pacman will run all the way through, so the thread to start the blue ghost has
+been commented out.  This program only runs through one level of the game.
+*/
+
 #include "mbed.h"
 #include "rtos.h"
 #include "uLCD_4DGL.h"
 
-#define PAC_SIZE    5
-#define STEP_SIZE   8
-#define CLEARANCE   12
+#define PAC_SIZE    5   //The radius of Pacman and the ghost
+#define STEP_SIZE   8   //The number of pixels each character moves at once
+#define CLEARANCE   12  //The number of pixels each character checks ahead before moving
 
 AnalogIn jsx(p19);  // The joysticks origin is about 1.6V in both directions
-AnalogIn jsy(p20);  // For just three states in each direction use thresholds 1.1V and 2V
+AnalogIn jsy(p20);  // For just three states in each direction, thresholds .33V and 3V were used
 uLCD_4DGL uLCD(p28, p27, p29);
 Mutex lcd_mutex;
 
-void checkMOVE(void);
+void checkMOVE(void);   //This function is defined below.  It was written here since other functions return to it that it also calls.
 
-volatile bool win=false;
-volatile bool lose=false;
-volatile int x = 64;
+//several variables are used by multiple threads
+volatile bool win=false;    //True when pacman has eaten all coins
+volatile bool lose=false;   //True when the position of the ghost and pacman are the same
+volatile int x = 64;        //x and y are pacman's position.  The starting position is defined here.
 volatile int y = 88;
-//volatile int x = 0;
-//volatile int y = 0;
-volatile int gx1 = 64;
+volatile int gx1 = 64;      //Starting position of the blue ghost
 volatile int gy1 = 40;
-volatile int pixel;
 int i;
 bool clearRIGHT,clearLEFT,clearUP,clearDOWN,bgcr,bgcl,bgcu,bgcd;
+
+//An array containing the locations of the 81 coins pacman must eat
 int coins[81][2] = {
         {40,88},{48,88},{56,88},{72,88},{80,88},{88,88},
         {40,40},{48,40},{56,40},{64,40},{72,40},{80,40},{88,40},
@@ -45,19 +51,21 @@
         {72,24},{72,32}
     };
 
+//This function is used in the ghost thread to replace coins as it passes over them
 void replaceCOINS(void)
 {
     for(int n=0; n<81; n++)
     {
-        lcd_mutex.lock();
+        lcd_mutex.lock();   //The coins array is used by both threads
         if(gx1 == coins[n][0] && gy1 == coins[n][1])
         {
-            uLCD.filled_circle(gx1,gy1,1,0xFFFF00);    
+            uLCD.filled_circle(gx1,gy1,1,0xFFFF00);     //compare the set of coins to the ghost's previous position and if there is a match redraw coin   
         }
         lcd_mutex.unlock();
     }
 }
 
+//Checks if the ghost can move right (there is no boundary immediately to the right)
 void BGclearRIGHT(void)
 {
     bgcr = true;
@@ -66,12 +74,13 @@
         lcd_mutex.lock();
         if(uLCD.read_pixel(p,gy1)==uLCD.read_pixel(4,4))
         {
-            bgcr = false;
-        }
+            bgcr = false;   //compare the pixels immediately in front of the ghost to the boundary up to the spec. clearance
+        }                   //if they are the same color, determine the ghost can't move right
         lcd_mutex.unlock();
     }
 }
 
+//Checks if ghost can move left
 void BGclearLEFT(void)
 {
     bgcl = true;
@@ -86,6 +95,7 @@
     }
 }
 
+//Checks if ghost can move up
 void BGclearUP(void)
 {
     bgcu = true;
@@ -100,6 +110,7 @@
     }
 }
 
+//Checks if ghost can move down
 void BGclearDOWN(void)
 {
     bgcd = true;
@@ -114,19 +125,21 @@
     }
 }
 
+//Moves the blue ghost to the right
 void bgRIGHT(void)
 {
     Thread::wait(50);
     lcd_mutex.lock();
-    uLCD.filled_rectangle(gx1-PAC_SIZE,gy1-PAC_SIZE,gx1+PAC_SIZE,gy1+PAC_SIZE,BLACK);
+    uLCD.filled_rectangle(gx1-PAC_SIZE,gy1-PAC_SIZE,gx1+PAC_SIZE,gy1+PAC_SIZE,BLACK);   //erase the previous ghost drawing
     lcd_mutex.unlock();
-    replaceCOINS();
-    if(gx1>124)
+    replaceCOINS();     //replace the coin the ghost was just on if there was one
+    if(gx1>124)         //This will cause the ghost to wrap around to the left side of the screen if there were no boundary on the far right
     {
         gx1 = 0;
     }
-    gx1 = gx1+STEP_SIZE;
+    gx1 = gx1+STEP_SIZE;    //Move one step size in the x direction
     lcd_mutex.lock();
+    //redraw the ghost at the new position
     uLCD.filled_circle(gx1,gy1,PAC_SIZE,BLUE);
     uLCD.filled_rectangle(gx1-PAC_SIZE,gy1,gx1+PAC_SIZE,gy1+PAC_SIZE,BLUE);
     uLCD.filled_circle(gx1+2,gy1-2,1,BLACK);
@@ -134,6 +147,7 @@
     lcd_mutex.unlock();
 }
 
+//Moves the blue ghost left
 void bgLEFT(void)
 {
     Thread::wait(50);
@@ -154,6 +168,7 @@
     lcd_mutex.unlock();
 }
 
+//Moves the blue ghost up
 void bgUP(void)
 {
     Thread::wait(50);
@@ -174,6 +189,7 @@
     lcd_mutex.unlock();
 }
 
+//Moves the blue ghost down
 void bgDOWN(void)
 {
     Thread::wait(50);
@@ -194,16 +210,17 @@
     lcd_mutex.unlock();
 }
 
+//Force ghost to chase Pacman
 void follow(void)
 {
-    if(x==gx1 && y==gy1)
+    if(x==gx1 && y==gy1)    //if the ghost and Pacman are at the same position trigger losing condition
     {
-        win = true;
+        win = true;         //This is set to true just to exit the check for a win loop and terminate other loops without writing additional conditions
         lose = true;
     }
-    while(x==gx1 && gy1<y && !win)
+    while(x==gx1 && gy1<y && !win)  //If the ghost is directly above Pacman check to see if moving down is possible, then move down
     {
-        BGclearDOWN();
+        BGclearDOWN();  
         bgDOWN();
     }
     while(x==gx1 && gy1>y && !win)
@@ -223,19 +240,18 @@
     }
 }
 
+//Ghost selects a direction to move
 void pickMOVE(void)
 {
-    while((gx1==x || gy1==y) && abs(x-gx1)+abs(y-gy1)<=16 && !win)
+    while((gx1==x || gy1==y) && abs(x-gx1)+abs(y-gy1)<=16 && !win)  //If Pacman is close by give chase
     {
         follow();
-        //Thread::wait(100);
     }
-    int dec = rand()%4;
-    //int dec = 0;
+    int dec = rand()%4; //randomly generate a number from the set 0,1,2,3, which serves as the direction decision
     if(dec == 0)
     {
         BGclearRIGHT();
-        while(bgcr && !win)
+        while(bgcr && !win)     //If decision 0 was reached, check to the the move right until a boundary is reached
         {
             bgRIGHT();
             BGclearRIGHT();
@@ -270,6 +286,7 @@
     }
 }        
 
+//Check if Pacman can move one step size to the right (Essentially the same as checking for the ghost)
 void CHECKclearRIGHT(void)
 {
     clearRIGHT = true;
@@ -284,6 +301,7 @@
     }
 }
 
+//Check if Pacman can move left
 void CHECKclearLEFT(void)
 {
     clearLEFT = true;
@@ -298,6 +316,7 @@
     }
 }
 
+//Check if Pacman can move up
 void CHECKclearUP(void)
 {
     clearUP = true;
@@ -312,6 +331,7 @@
     }
 }
 
+//Check if Pacman can move down
 void CHECKclearDOWN(void)
 {
     clearDOWN = true;
@@ -326,35 +346,37 @@
     }
 }
 
+//This function tracks the coin Pacman eats as he passes over it
 void changeCOINS(void)
 {
     for(int m=0; m<81; m++)
     {
         lcd_mutex.lock();
-        if(x == coins[m][0] && y == coins[m][1])
+        if(x == coins[m][0] && y == coins[m][1])    //Compare Pacman's position to the set of coins
         {
-            coins[m][0]=64;
-            coins[m][1]=64;
+            coins[m][0]=64;                         //If there is a match, change that coins location to the center of the board where Pacman
+            coins[m][1]=64;                         //cannot go, but do not draw the coin
         }
         lcd_mutex.unlock();
     }
 }
 
+//Move Pacman one step size to the right
 void PACmoveRIGHT(void)
 {
-    while(clearRIGHT && !win)
+    while(clearRIGHT && !win)   //Not win indicates the game has not ended
     {
         lcd_mutex.lock();
-        uLCD.filled_circle(x,y,PAC_SIZE,BLACK);
+        uLCD.filled_circle(x,y,PAC_SIZE,BLACK);     //Erase Pacman at his last location
         lcd_mutex.unlock();
-        if(x>124)
+        if(x>124)       //wrap around if moving off the board
         {
             x = 0;
         }
-        x = x+STEP_SIZE;
-        changeCOINS();
+        x = x+STEP_SIZE;    //move Pacman one step size to the right
+        changeCOINS();  //Track the coin that was eaten at the last location
         
-        if(x%(2*STEP_SIZE) == 0)
+        if(x%(2*STEP_SIZE) == 0)    //There are two drawings provided for Pacman.  The if statement causes Pacman to open his mouth every other move.
         {
             lcd_mutex.lock();
             uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00);
@@ -368,15 +390,16 @@
             uLCD.filled_rectangle(x+2,y,x+PAC_SIZE,y+1,BLACK);
             lcd_mutex.unlock();
         }
-        if(jsx <= .75)
+        if(jsx <= .9)       //If the user is still holding the joystick to the right, remain in this loop
         {
             checkMOVE();
         }
-        CHECKclearRIGHT();
+        CHECKclearRIGHT();  //If the user remains in the loop, check for a boundary to the right
         Thread::wait(10);
     }
 }
 
+//Move Pacman left
 void PACmoveLEFT(void)
 {
     while(clearLEFT && !win)
@@ -413,6 +436,7 @@
     }
 }
 
+//Move Pacman up
 void PACmoveUP(void)
 {
     while(clearUP && !win)
@@ -449,6 +473,7 @@
     }
 }
 
+//Move Pacman down
 void PACmoveDOWN(void)
 {
     while(clearDOWN && !win)
@@ -485,6 +510,8 @@
     }
 }
 
+//Read the input from the joystick and select a direction to move
+//The thresholds are set near the end of their ranges to eliminate unintentional moves as much as possible
 void checkMOVE(void)
 {
     if(jsx > .9)
@@ -509,6 +536,7 @@
     }
 }
 
+//Draw the boudaries for the game using the uLCD graphics commands
 void drawBORDERS(void)
 {
     //Outer Border
@@ -562,10 +590,11 @@
 {
     for(int j=0; j<81; j++)
     {
-        uLCD.filled_circle(coins[j][0],coins[j][1],1,0xFFFF00);
+        uLCD.filled_circle(coins[j][0],coins[j][1],1,0xFFFF00);     //Draw the coins in their initial locations
     }
 }
 
+//Draw all the initial states of the game
 void initialize(void)
 {
     drawBORDERS();
@@ -574,13 +603,14 @@
     uLCD.filled_rectangle(x-2,y-2,x-PAC_SIZE,y+2,BLACK);
 }
 
+//Check to see if all the coins have been eaten
 void checkWIN(void)
 {
     win = true;
     for(int k=0; k<81; k++)
     {
         lcd_mutex.lock();
-        if(coins[k][0]!=64 || coins[k][1]!=64)
+        if(coins[k][0]!=64 || coins[k][1]!=64)  //Check the locations of all coins and if 1 has coordinates other than (64,64) the user has not won
         {
             win = false;
         }
@@ -588,6 +618,7 @@
     }
 }
 
+//Thread supervising the joystick inputs and moving Pacman accordingly
 void pacMOVE(void const *args)
 {
     while(!win)
@@ -597,6 +628,7 @@
     }
 }
 
+//Thread controlling the movement of the blue ghost
 void blueGHOST(void const *args)
 {
     while(!win)
@@ -608,29 +640,21 @@
 int main()
 {
     uLCD.cls();
-    //uLCD.background_color(DGREY);
     uLCD.baudrate(BAUD_3000000);
-    //int x=64,y=64,
-    //int xy[2]={64,64};
-    //Thread t1(thread1,&x1,&y1);
-    initialize();
-    Thread pm(pacMOVE);
-    Thread bg(blueGHOST);
-    //Thread clr(clear);
-    //pixel = uLCD.read_pixel(128,128);
-    //for(int k=0; k<10; k++){
-    //i = rand();
-    //uLCD.printf("rand = %d\n",rand());
-    Thread::wait(5000);
+    initialize();                   //Draw the level setup
+    Thread pm(pacMOVE);             //Start the thread for moving Pacman
+    //Thread bg(blueGHOST);         //Start the thread for moving the blue ghost
     
-    while(!win)
+    Thread::wait(5000);             //Wait some time before checking the win conditions since it will take around 30 secs to eat all 81 coins
+    while(!win)                     //Check to see if there was a win once every  tenth of a second
     {
         checkWIN();
-        Thread::wait(1000);
+        Thread::wait(100);
     }
-    //uLCD.printf("WIN");
-    Thread::wait(1000);
-    if(lose)
+    
+    Thread::wait(1000);             //Wait one second before displaying end message
+    
+    if(lose)                        //Print game over message if lose (determined in the follow function)
     {
         uLCD.cls();
         uLCD.printf("Sorry\nGame Over");
@@ -638,8 +662,6 @@
     else
     {
         uLCD.cls();
-        //uLCD.locate(60,60);
-        //uLCD.set_font_size(10,10);
         uLCD.printf("Congratulations!\nYou Won!");
     }