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