Code for 4180 mini project

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

Fork of Pacman by Shawn Rigdon

Revision:
2:610d5194c64e
Parent:
1:b86030cf57c4
--- a/main.cpp	Tue Mar 25 18:49:05 2014 +0000
+++ b/main.cpp	Wed Oct 21 19:53:10 2015 +0000
@@ -1,35 +1,36 @@
-/*
-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"
+#include "SDFileSystem.h"
+#include "wave_player.h"
 
-#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
+#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, thresholds .33V and 3V were used
+DigitalIn left_pb(p21);  // push button
+DigitalIn right_pb(p22); // push button
+DigitalIn up_pb(p23);    // push button
+DigitalIn down_pb(p24);  // push button
+SDFileSystem sd(p5, p6, p7, p8, "sd"); //SD card
+AnalogOut DACout(p18);
+wave_player waver(&DACout); // wave player
 uLCD_4DGL uLCD(p28, p27, p29);
 Mutex lcd_mutex;
 
-void checkMOVE(void);   //This function is defined below.  It was written here since other functions return to it that it also calls.
+void checkMOVE(void);   // This function is defined below.  It was written here since other functions return to it that it also calls.
 
-//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.
+// 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 gx1 = 64;      //Starting position of the blue ghost
+volatile int gx1 = 64;      // Starting position of the blue ghost
 volatile int gy1 = 40;
 int i;
 bool clearRIGHT,clearLEFT,clearUP,clearDOWN,bgcr,bgcl,bgcu,bgcd;
 
-//An array containing the locations of the 81 coins pacman must eat
+// 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},
@@ -51,7 +52,7 @@
         {72,24},{72,32}
     };
 
-//This function is used in the ghost thread to replace coins as it passes over them
+// 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++)
@@ -65,7 +66,7 @@
     }
 }
 
-//Checks if the ghost can move right (there is no boundary immediately to the right)
+// Checks if the ghost can move right (there is no boundary immediately to the right)
 void BGclearRIGHT(void)
 {
     bgcr = true;
@@ -74,8 +75,8 @@
         lcd_mutex.lock();
         if(uLCD.read_pixel(p,gy1)==uLCD.read_pixel(4,4))
         {
-            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
+            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();
     }
 }
@@ -213,10 +214,23 @@
 //Force ghost to chase Pacman
 void follow(void)
 {
-    if(x==gx1 && y==gy1)    //if the ghost and Pacman are at the same position trigger losing condition
+    if((gx1==x) && (y == gy1) )    //if the ghost and Pacman are at the same position trigger losing condition
     {
         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;
+        if(lose)            //Print game over message if lose (determined in the follow function)
+        {
+            uLCD.cls();
+            uLCD.printf("Sorry\nGame Over");
+            // if loss, ring the buzzer
+            FILE *wave_file;
+            wave_file=fopen("/sd/test.wav","r");
+            waver.play(wave_file);
+            fclose(wave_file);
+            Thread::wait(1000);
+            return void();
+        }
+
     }
     while(x==gx1 && gy1<y && !win)  //If the ghost is directly above Pacman check to see if moving down is possible, then move down
     {
@@ -242,7 +256,8 @@
 
 //Ghost selects a direction to move
 void pickMOVE(void)
-{
+{   
+    
     while((gx1==x || gy1==y) && abs(x-gx1)+abs(y-gy1)<=16 && !win)  //If Pacman is close by give chase
     {
         follow();
@@ -390,12 +405,10 @@
             uLCD.filled_rectangle(x+2,y,x+PAC_SIZE,y+1,BLACK);
             lcd_mutex.unlock();
         }
-        if(jsx <= .9)       //If the user is still holding the joystick to the right, remain in this loop
-        {
-            checkMOVE();
-        }
+        
         CHECKclearRIGHT();  //If the user remains in the loop, check for a boundary to the right
         Thread::wait(10);
+        break;
     }
 }
 
@@ -412,6 +425,7 @@
             x = 128;
         }
         x = x-STEP_SIZE;
+        
         changeCOINS();
         if(x%(2*STEP_SIZE) == 0)
         {
@@ -427,12 +441,10 @@
             uLCD.filled_rectangle(x-2,y,x-PAC_SIZE,y+1,BLACK);
             lcd_mutex.unlock();
         }
-        if(jsx >= .1)
-        {
-            checkMOVE();
-        }
+        
         CHECKclearLEFT();
         Thread::wait(10);
+        break;
     }
 }
 
@@ -464,12 +476,10 @@
             uLCD.filled_rectangle(x,y-2,x+1,y-PAC_SIZE,BLACK);
             lcd_mutex.unlock();
         }
-        if(jsy <= .9)
-        {
-            checkMOVE();
-        }
+        
         CHECKclearUP();
         Thread::wait(10);
+        break;
     }
 }
 
@@ -501,36 +511,26 @@
             uLCD.filled_rectangle(x,y+2,x+1,y+PAC_SIZE,BLACK);
             lcd_mutex.unlock();
         }
-        if(jsy >= .1)
-        {
-            checkMOVE();
-        }
+        
         CHECKclearDOWN();
         Thread::wait(10);
+        break;
     }
 }
 
-//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
+//Read the input from pushbuttons
 void checkMOVE(void)
 {
-    if(jsx > .9)
-    {
+    if(!right_pb) {
         CHECKclearRIGHT();
         PACmoveRIGHT();
-    }
-    else if(jsx < .1)
-    {
+    } else if(!left_pb) {
         CHECKclearLEFT();
         PACmoveLEFT();
-    }
-    if(jsy > .9)
-    {
+    } else if(!up_pb){
         CHECKclearUP();
         PACmoveUP();
-    }
-    else if(jsy < .1)
-    {
+    } else if(!down_pb){
         CHECKclearDOWN();
         PACmoveDOWN();
     }
@@ -624,7 +624,7 @@
     while(!win)
     {
         checkMOVE();
-        Thread::wait(10);
+        Thread::wait(1);
     }
 }
 
@@ -639,22 +639,26 @@
 
 int main()
 {
+    left_pb.mode(PullUp);  // The variable left_pb will be zero when the pushbutton for moving the player left is pressed    
+    right_pb.mode(PullUp); // The variable rightt_pb will be zero when the pushbutton for moving the player right is pressed        
+    up_pb.mode(PullUp);    // the variable fire_pb will be zero when the pushbutton for firing a missile is pressed
+    down_pb.mode(PullUp);  // the variable fire_pb will be zero when the pushbutton for firing a missile is pressed
     uLCD.cls();
     uLCD.baudrate(BAUD_3000000);
-    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
+    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
     
-    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
+    Thread::wait(3000000000);       // 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(100);
+        Thread::wait(1);
     }
     
-    Thread::wait(1000);             //Wait one second before displaying end message
+    Thread::wait(500);              // Wait .5 second before displaying end message
     
-    if(lose)                        //Print game over message if lose (determined in the follow function)
+    if(lose)                        // Print game over message if lose (determined in the follow function)
     {
         uLCD.cls();
         uLCD.printf("Sorry\nGame Over");
@@ -665,5 +669,6 @@
         uLCD.printf("Congratulations!\nYou Won!");
     }
     
-    while(1){}
+    
+    while(1){Thread::wait(1);}
 }
\ No newline at end of file