Eric Xu / Mbed 2 deprecated Pac-Man

Dependencies:   4DGL-uLCD-SE PinDetect mbed

Fork of Pac-Man by Eric Xu

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Ghost.h Source File

Ghost.h

00001 /******************************************************
00002  * Author: Yuanzhe Xu
00003  * Institution: Georgia Institute of Technology
00004  * Date: October 18, 2015
00005  *
00006  * This header file declares all the functions and
00007  * variables needed for the Ghost object. Specific
00008  * ghost functionalities can be found in main.cpp.
00009  ******************************************************/
00010 
00011 // Ghost class
00012 class Ghost {
00013     public:
00014         // Ghost constructor
00015         Ghost(int color, uLCD_4DGL& uLCD, Stage& stage, Pacman& pacman)
00016             : color(color), uLCD(uLCD), stage(stage), pacman(pacman) {
00017         }
00018 
00019         // Initialize the ghost at the beginning of the game
00020         void initialize(int xCoordinate, int yCoordinate, int facingDirection) {
00021             startingX = xCoordinate;
00022             startingY = yCoordinate;
00023             x = xCoordinate;
00024             y = yCoordinate;
00025             direction = facingDirection;
00026             immobile = false;
00027             draw(x, y);
00028         }
00029 
00030         // Set the next direction
00031         void setNextDirection(int next) {
00032             previousDirection = (direction + 2) % 4;
00033 
00034             // If the next direction is not its previous direction
00035             if (next != previousDirection) {
00036                 // Set the next direction to next
00037                 nextDirection = next;
00038             }
00039         }
00040 
00041         // Move the ghost
00042         void move() {
00043             // If Pac-Man died
00044             if (pacman.dead == true) {
00045                 // Reset the ghost
00046                 erase(x, y);
00047                 reinitialize();
00048                 pacman.dead = false;
00049             }
00050 
00051             // If the ghost is not moving
00052             if (immobile == true) {
00053                 // Reset the ghost
00054                 erase(x, y);
00055                 stage.redrawPacDots();
00056                 reinitialize();
00057             }
00058 
00059             // Move the ghost in its current direction
00060             switch (direction) {
00061                 case FACERIGHT:
00062                     moveRight();
00063                     break;
00064                 case FACEDOWN:
00065                     moveDown();
00066                     break;
00067                 case FACELEFT:
00068                     moveLeft();
00069                     break;
00070                 case FACEUP:
00071                     moveUp();
00072                     break;
00073                 default:
00074                     break;
00075             }
00076 
00077             // If Pac-Man and the ghost occupy the same position
00078             if ((abs(pacman.x - x) < 5) && (abs(pacman.y - y) < 5)) {
00079                 // If Pac-Man is not invincible
00080                 if (pacman.powerUp == 0) {
00081                     // Reset Pac-Man and the ghost
00082                     pacman.ghostsEaten = 0;
00083                     pacman.erase(pacman.x, pacman.y);
00084                     erase(x, y);
00085                     pacman.draw(pacman.x, pacman.y);
00086                     wait(0.5);
00087                     pacman.die();
00088                     pacman.dead = true;
00089                     reinitialize();
00090                 // If Pac-Man is invincible
00091                 } else {
00092                     // Reset the ghost
00093                     pacman.ghostsEaten++;
00094                     pacman.score += pacman.ghostsEaten * 200;
00095                     pacman.scoreChanged = true;
00096                     erase(x, y);
00097                     stage.redrawPacDots();
00098                     pacman.draw(pacman.x, pacman.y);
00099                     wait(0.5);
00100                     reinitialize();
00101                 }
00102             }
00103         }
00104 
00105 
00106     private:
00107         // The ghost's color
00108         int color;
00109         // Starting horizontal position
00110         int startingX;
00111         // Starting vertical position
00112         int startingY;
00113         // Current horizontal position
00114         int x;
00115         // Current vertical position
00116         int y;
00117         // Previous direction
00118         int previousDirection;
00119         // Current direction
00120         int direction;
00121         // Next direction
00122         int nextDirection;
00123         // Ghost resets when immobile is true
00124         bool immobile;
00125         // uLCD display
00126         uLCD_4DGL& uLCD;
00127         // Stage reference
00128         Stage& stage;
00129         // Pacman reference
00130         Pacman& pacman;
00131 
00132         // Reset function for each ghost
00133         void reinitialize() {
00134             // Red ghost reset
00135             if (color == RED) {
00136                 initialize(startingX, startingY, FACELEFT);
00137             // Yellow ghost reset
00138             } else if (color == YELLOW) {
00139                 initialize(startingX, startingY, FACERIGHT);
00140             }
00141         }
00142 
00143         // Draw the ghost based on its direction
00144         void draw(int xCoordinate, int yCoordinate) {
00145             // Outer bound rectangular coordinates of the ghost
00146             int x1 = xCoordinate - 3;
00147             int x2 = xCoordinate + 3;
00148             int y1 = yCoordinate - 3;
00149             int y2 = yCoordinate + 3;
00150 
00151             // If Pac-Man is currently invincible
00152             if (pacman.powerUp > 0) {
00153                 // Draw the ghost in blue
00154                 uLCD.filled_rectangle(x1, y1, x2, y2, BLUE);
00155             // If Pac-Man is not currently invincible
00156             } else {
00157                 // Draw the ghost in its original color
00158                 uLCD.filled_rectangle(x1, y1, x2, y2, color);
00159             }
00160 
00161             // Specify the pixels
00162             uLCD.pixel(x1, y1, BLACK);
00163             uLCD.pixel(x2, y1, BLACK);
00164             uLCD.pixel(xCoordinate - 2, y2, BLACK);
00165             uLCD.pixel(xCoordinate, y2, BLACK);
00166             uLCD.pixel(xCoordinate + 2, y2, BLACK);
00167             uLCD.pixel(x1, yCoordinate - 1, WHITE);
00168             uLCD.pixel(xCoordinate - 2, yCoordinate - 2, WHITE);
00169             uLCD.pixel(xCoordinate - 2, yCoordinate - 1, WHITE);
00170             uLCD.pixel(xCoordinate - 2, yCoordinate, WHITE);
00171             uLCD.pixel(xCoordinate - 1, yCoordinate - 1, WHITE);
00172             uLCD.pixel(x2, yCoordinate - 1, WHITE);
00173             uLCD.pixel(xCoordinate + 2, yCoordinate - 2, WHITE);
00174             uLCD.pixel(xCoordinate + 2, yCoordinate - 1, WHITE);
00175             uLCD.pixel(xCoordinate + 2, yCoordinate, WHITE);
00176             uLCD.pixel(xCoordinate + 1, yCoordinate - 1, WHITE);
00177 
00178             // Draw the ghost's eyes based on its current direction
00179             switch (direction) {
00180                 case FACERIGHT:
00181                     uLCD.pixel(xCoordinate - 1, yCoordinate - 1, BLACK);
00182                     uLCD.pixel(x2, yCoordinate - 1, BLACK);
00183                     break;
00184                 case FACEDOWN:
00185                     uLCD.pixel(xCoordinate - 2, yCoordinate, BLACK);
00186                     uLCD.pixel(xCoordinate + 2, yCoordinate, BLACK);
00187                     break;
00188                 case FACELEFT:
00189                     uLCD.pixel(x1, yCoordinate - 1, BLACK);
00190                     uLCD.pixel(xCoordinate + 1, yCoordinate - 1, BLACK);
00191                     break;
00192                 case FACEUP:
00193                     uLCD.pixel(xCoordinate - 2, yCoordinate - 2, BLACK);
00194                     uLCD.pixel(xCoordinate + 2, yCoordinate - 2, BLACK);
00195                     break;
00196                 default:
00197                     break;
00198             }
00199         }
00200 
00201         // Erase the ghost from the given position
00202         void erase(int xCoordinate, int yCoordinate) {
00203             int x1 = xCoordinate - 3;
00204             int x2 = xCoordinate + 3;
00205             int y1 = yCoordinate - 3;
00206             int y2 = yCoordinate + 3;
00207             uLCD.filled_rectangle(x1, y1, x2, y2, BLACK);
00208         }
00209 
00210         // Move the ghost right
00211         void moveRight() {
00212             // If the space to the right is a valid position and is not the rightmost space
00213             if ((stage.positions[x + 1][y] != 0) && (x != 124)) {
00214                 // The ghost is mobile
00215                 immobile = false;
00216                 // Erase the ghost from its current position
00217                 erase(x, y);
00218                 // Increment the ghost's x-coordinate
00219                 x++;
00220 
00221                 // If passed over a pac dot
00222                 if (stage.positions[x - 4][y] == 2) {
00223                     // Redraw the pac dot
00224                     uLCD.pixel(x - 4, y, YELLOW);
00225                 // If passed over a big pac dot
00226                 } else {
00227                     // Redraw the big pac dot
00228                     for (int i = x - 2; i >= x - 5; i--) {
00229                         if (stage.positions[i][y] == 3) {
00230                             uLCD.filled_circle(i, y, 1, YELLOW);
00231                         }
00232                     }
00233                 }
00234 
00235                 // Draw the ghost in its new position
00236                 draw(x, y);
00237             // If the space to the right is not a valid positions
00238             } else if (stage.positions[x + 1][y] == 0) {
00239                 // The ghost is immobile
00240                 immobile = true;
00241                 wait(0.03);
00242             }
00243 
00244             // If the rightmost position is reached
00245             if (x == 124) {
00246                 // The ghost is mobile
00247                 immobile = false;
00248                 // Erase the ghost from its current position
00249                 erase(x, y);
00250                 // Set the ghost's x-coordinate to 4
00251                 x = 4;
00252 
00253                 // If passed over a pac dot
00254                 if (stage.positions[124][68] == 2) {
00255                     // Redraw the pac dot
00256                     uLCD.pixel(124, 68, YELLOW);
00257                 }
00258 
00259                 // Draw the ghost in its new position
00260                 draw(x, y);
00261             }
00262 
00263             // If Pac-Man's invincibility status changed
00264             if (pacman.powerUpChanged == true) {
00265                 // Change the color of the ghost
00266                 draw(x, y);
00267                 // Reset Pac-Man's invincibility status change
00268                 pacman.powerUpChanged = false;
00269             }
00270 
00271             // Set the ghost's next direction
00272             switch (nextDirection) {
00273                 case FACEDOWN:
00274                     if (stage.positions[x][y + 1] != 0) {
00275                         direction = nextDirection;
00276                     }
00277     
00278                     break;
00279                 case FACELEFT:
00280                     if (stage.positions[x - 1][y] != 0) {
00281                         direction = nextDirection;
00282                     }
00283     
00284                     break;
00285                 case FACEUP:
00286                     if (stage.positions[x][y - 1] != 0) {
00287                         direction = nextDirection;
00288                     }
00289     
00290                     break;
00291                 default:
00292                     break;
00293             }
00294         }
00295 
00296         // Move the ghost down
00297         void moveDown() {
00298             // If the space in the downward direction is a valid position
00299             if (stage.positions[x][y + 1] != 0) {
00300                 // The ghost is mobile
00301                 immobile = false;
00302                 // Erase the ghost from its current position
00303                 erase(x, y);
00304                 // Increment the ghost's y-coordinate
00305                 y++;
00306 
00307                 // If passed over a pac dot
00308                 if (stage.positions[x][y - 4] == 2) {
00309                     // Redraw the pac dot
00310                     uLCD.pixel(x, y - 4, YELLOW);
00311                 // If passed over a big pac dot
00312                 } else {
00313                     // Redraw the big pac dot
00314                     for (int j = y - 2; j >= y - 5; j--) {
00315                         if (stage.positions[x][j] == 3) {
00316                             uLCD.filled_circle(x, j, 1, YELLOW);
00317                         }
00318                     }
00319                 }
00320 
00321                 // Draw the ghost in its new position
00322                 draw(x, y);
00323             // If the space in the downward direction is not a valid position
00324             } else {
00325                 // The ghost is immobile
00326                 immobile = true;
00327                 wait(0.03);
00328             }
00329 
00330             // If Pac-Man's invincibility status changed
00331             if (pacman.powerUpChanged == true) {
00332                 // Change the color of the ghost
00333                 draw(x, y);
00334                 // Reset Pac-Man's invincibility status change
00335                 pacman.powerUpChanged = false;
00336             }
00337 
00338             // Set the ghost's next direction
00339             switch (nextDirection) {
00340                 case FACERIGHT:
00341                     if (stage.positions[x + 1][y] != 0) {
00342                         direction = nextDirection;
00343                     }
00344 
00345                     break;
00346                 case FACELEFT:
00347                     if (stage.positions[x - 1][y] != 0) {
00348                         direction = nextDirection;
00349                     }
00350 
00351                     break;
00352                 case FACEUP:
00353                     if (stage.positions[x][y - 1] != 0) {
00354                         direction = nextDirection;
00355                     }
00356 
00357                     break;
00358                 default:
00359                     break;
00360             }
00361         }
00362 
00363         // Move the ghost left
00364         void moveLeft() {
00365             // If the space to the left is a valid position and is not the leftmost space
00366             if ((stage.positions[x - 1][y] != 0) && (x != 4)) {
00367                 // The ghost is mobile
00368                 immobile = false;
00369                 // Erase the ghost from its current position
00370                 erase(x, y);
00371                 // Decrement the ghost's x-coordinate
00372                 x--;
00373 
00374                 // If passed over a pac dot
00375                 if (stage.positions[x + 4][y] == 2) {
00376                     // Redraw the pac dot
00377                     uLCD.pixel(x + 4, y, YELLOW);
00378                 // If passed over a big pac dot
00379                 } else {
00380                     // Redraw the big pac dot
00381                     for (int i = x + 2; i <= x + 5; i++) {
00382                         if (stage.positions[i][y] == 3) {
00383                             uLCD.filled_circle(i, y, 1, YELLOW);
00384                         }
00385                     }
00386                 }
00387 
00388                 // Draw the ghost in its new position
00389                 draw(x, y);
00390             // If the space to the left is not a valid position
00391             } else if (stage.positions[x - 1][y] == 0) {
00392                 // The ghost is immobile
00393                 immobile = true;
00394                 wait(0.03);
00395             }
00396 
00397             // If the leftmost position is reached
00398             if (x == 4) {
00399                 // The ghost is mobile
00400                 immobile = false;
00401                 // Erase the ghost from its current position
00402                 erase(x, y);
00403                 // Set the ghost's x-coordinate to 124
00404                 x = 124;
00405 
00406                 // If passed over a pac dot
00407                 if (stage.positions[4][68] == 2) {
00408                     // Redraw the pac dot
00409                     uLCD.pixel(4, 68, YELLOW);
00410                 }
00411 
00412                 // Draw the ghost in its new position
00413                 draw(x, y);
00414             }
00415 
00416             // If Pac-Man's invincibility status changed
00417             if (pacman.powerUpChanged == true) {
00418                 // Change the color of the ghost
00419                 draw(x, y);
00420                 // Reset Pac-Man's invincibility status change
00421                 pacman.powerUpChanged = false;
00422             }
00423 
00424             // Set the ghost's next direction
00425             switch (nextDirection) {
00426                 case FACERIGHT:
00427                     if (stage.positions[x + 1][y] != 0) {
00428                         direction = nextDirection;
00429                     }
00430 
00431                     break;
00432                 case FACEDOWN:
00433                     if (stage.positions[x][y + 1] != 0) {
00434                         direction = nextDirection;
00435                     }
00436 
00437                     break;
00438                 case FACEUP:
00439                     if (stage.positions[x][y - 1] != 0) {
00440                         direction = nextDirection;
00441                     }
00442 
00443                     break;
00444                 default:
00445                     break;
00446             }
00447         }
00448 
00449         // Move the ghost up
00450         void moveUp() {
00451             // If the space in the upward direction is a valid position
00452             if (stage.positions[x][y - 1] != 0) {
00453                 // The ghost is mobile
00454                 immobile = false;
00455                 // Erase the ghost from its current position
00456                 erase(x, y);
00457                 // Decrement the ghost's y-coordinate
00458                 y--;
00459 
00460                 // If passed over a pac dot
00461                 if (stage.positions[x][y + 4] == 2) {
00462                     // Redraw the pac dot
00463                     uLCD.pixel(x, y + 4, YELLOW);
00464                 // If passed over a big pac dot
00465                 } else {
00466                     // Redraw the big pac dot
00467                     for (int j = y + 2; j <= y + 5; j++) {
00468                         if (stage.positions[x][j] == 3) {
00469                             uLCD.filled_circle(x, j, 1, YELLOW);
00470                         }
00471                     }
00472                 }
00473 
00474                 // Draw the ghost in its new position
00475                 draw(x, y);
00476             // If the space in the upward direction is not a valid position
00477             } else {
00478                 // The ghost is immobile
00479                 immobile = true;
00480                 wait(0.03);
00481             }
00482 
00483             // If Pac-Man's invincibility status changed
00484             if (pacman.powerUpChanged == true) {
00485                 // Change the color of the ghost
00486                 draw(x, y);
00487                 // Reset Pac-Man's invincibility status change
00488                 pacman.powerUpChanged = false;
00489             }
00490 
00491             // Set the ghost's next direction
00492             switch (nextDirection) {
00493                 case FACERIGHT:
00494                     if (stage.positions[x + 1][y] != 0) {
00495                         direction = nextDirection;
00496                     }
00497 
00498                     break;
00499                 case FACEDOWN:
00500                     if (stage.positions[x][y + 1] != 0) {
00501                         direction = nextDirection;
00502                     }
00503 
00504                     break;
00505                 case FACELEFT:
00506                     if (stage.positions[x - 1][y] != 0) {
00507                         direction = nextDirection;
00508                     }
00509 
00510                     break;
00511                 default:
00512                     break;
00513             }
00514         }
00515 };