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
- Committer:
- soapy12312
- Date:
- 2015-11-28
- Revision:
- 1:2a7e2f5aeda4
- Parent:
- 0:218d3fb75950
- Child:
- 2:da0f01fbd25c
File content as of revision 1:2a7e2f5aeda4:
/****************************************************** * Author: Yuanzhe Xu * Institution: Georgia Institute of Technology * Date: October 18, 2015 * * This header file declares all the functions and * variables needed for the Ghost object. Specific * ghost functionalities can be found in main.cpp. ******************************************************/ // Ghost class class Ghost { public: // Ghost constructor Ghost(int color, Pacman& pacman, PinDetect &ghostRight, PinDetect &ghostDown, PinDetect &ghostLeft, PinDetect &ghostUp, Stage& stage, uLCD_4DGL& uLCD) : color(color), pacman(pacman), ghostRight(ghostRight), ghostDown(ghostDown), ghostLeft(ghostLeft), ghostUp(ghostUp), stage(stage), uLCD(uLCD) { // Use internal pullups ghostRight.mode(PullUp); ghostDown.mode(PullUp); ghostLeft.mode(PullUp); ghostUp.mode(PullUp); wait(0.01); // Interrupt callback functions ghostRight.attach_deasserted(this, &Ghost::ghostRightTrigger); ghostDown.attach_deasserted(this, &Ghost::ghostDownTrigger); ghostLeft.attach_deasserted(this, &Ghost::ghostLeftTrigger); ghostUp.attach_deasserted(this, &Ghost::ghostUpTrigger); wait(0.01); // Set sampling frequency ghostRight.setSampleFrequency(); ghostDown.setSampleFrequency(); ghostLeft.setSampleFrequency(); ghostUp.setSampleFrequency(); wait(1); } // Initialize the ghost at the beginning of the game void initialize(int xCoordinate, int yCoordinate, int facingDirection) { startingX = xCoordinate; startingY = yCoordinate; x = xCoordinate; y = yCoordinate; direction = facingDirection; immobile = false; draw(x, y); } // Move the ghost void move() { // If Pac-Man died if (pacman.dead == true) { // Reset the ghost erase(x, y); reinitialize(); pacman.dead = false; } // If the ghost is not moving if (immobile == true) { // Reset the ghost erase(x, y); stage.redrawPacDots(); reinitialize(); } // Move the ghost in its current direction switch (direction) { case FACERIGHT: moveRight(); break; case FACEDOWN: moveDown(); break; case FACELEFT: moveLeft(); break; case FACEUP: moveUp(); break; default: break; } // If Pac-Man and the ghost occupy the same position if ((abs(pacman.x - x) < 5) && (abs(pacman.y - y) < 5)) { // If Pac-Man is not invincible if (pacman.powerUp == 0) { // Reset Pac-Man and the ghost pacman.ghostsEaten = 0; pacman.erase(pacman.x, pacman.y); erase(x, y); pacman.draw(pacman.x, pacman.y); wait(0.5); pacman.die(); pacman.dead = true; reinitialize(); // If Pac-Man is invincible } else { // Reset the ghost pacman.ghostsEaten++; pacman.score += pacman.ghostsEaten * 200; pacman.scoreChanged = true; erase(x, y); stage.redrawPacDots(); pacman.draw(pacman.x, pacman.y); wait(0.5); reinitialize(); } } } private: int color; Pacman& pacman; PinDetect &ghostRight; PinDetect &ghostDown; PinDetect &ghostLeft; PinDetect &ghostUp; Stage& stage; uLCD_4DGL& uLCD; int startingX; int startingY; int x; int y; volatile int previousDirection; int direction; volatile int nextDirection; bool immobile; // Set the next direction to be right void ghostRightTrigger() { previousDirection = (direction + 2) % 4; if (previousDirection != FACERIGHT) { nextDirection = FACERIGHT; } } // Set the next direction to be down void ghostDownTrigger() { previousDirection = (direction + 2) % 4; if (previousDirection != FACEDOWN) { nextDirection = FACEDOWN; } } // Set the next direction to be left void ghostLeftTrigger() { previousDirection = (direction + 2) % 4; if (previousDirection != FACELEFT) { nextDirection = FACELEFT; } } // Set the next direction to be up void ghostUpTrigger() { previousDirection = (direction + 2) % 4; if (previousDirection != FACEUP) { nextDirection = FACEUP; } } // Reset function for each ghost void reinitialize() { // Red ghost reset if (color == RED) { initialize(startingX, startingY, FACELEFT); // Yellow ghost reset } else if (color == YELLOW) { initialize(startingX, startingY, FACERIGHT); } } // Draw the ghost based on its direction void draw(int xCoordinate, int yCoordinate) { // Outer bound rectangular coordinates of the ghost int x1 = xCoordinate - 3; int x2 = xCoordinate + 3; int y1 = yCoordinate - 3; int y2 = yCoordinate + 3; // If Pac-Man is currently invincible if (pacman.powerUp > 0) { // Draw the ghost in blue uLCD.filled_rectangle(x1, y1, x2, y2, BLUE); // If Pac-Man is not currently invincible } else { // Draw the ghost in its original color uLCD.filled_rectangle(x1, y1, x2, y2, color); } // Specify the pixels uLCD.pixel(x1, y1, BLACK); uLCD.pixel(x2, y1, BLACK); uLCD.pixel(xCoordinate - 2, y2, BLACK); uLCD.pixel(xCoordinate, y2, BLACK); uLCD.pixel(xCoordinate + 2, y2, BLACK); uLCD.pixel(x1, yCoordinate - 1, WHITE); uLCD.pixel(xCoordinate - 2, yCoordinate - 2, WHITE); uLCD.pixel(xCoordinate - 2, yCoordinate - 1, WHITE); uLCD.pixel(xCoordinate - 2, yCoordinate, WHITE); uLCD.pixel(xCoordinate - 1, yCoordinate - 1, WHITE); uLCD.pixel(x2, yCoordinate - 1, WHITE); uLCD.pixel(xCoordinate + 2, yCoordinate - 2, WHITE); uLCD.pixel(xCoordinate + 2, yCoordinate - 1, WHITE); uLCD.pixel(xCoordinate + 2, yCoordinate, WHITE); uLCD.pixel(xCoordinate + 1, yCoordinate - 1, WHITE); // Draw the ghost's eyes based on its current direction switch (direction) { case FACERIGHT: uLCD.pixel(xCoordinate - 1, yCoordinate - 1, BLACK); uLCD.pixel(x2, yCoordinate - 1, BLACK); break; case FACEDOWN: uLCD.pixel(xCoordinate - 2, yCoordinate, BLACK); uLCD.pixel(xCoordinate + 2, yCoordinate, BLACK); break; case FACELEFT: uLCD.pixel(x1, yCoordinate - 1, BLACK); uLCD.pixel(xCoordinate + 1, yCoordinate - 1, BLACK); break; case FACEUP: uLCD.pixel(xCoordinate - 2, yCoordinate - 2, BLACK); uLCD.pixel(xCoordinate + 2, yCoordinate - 2, BLACK); break; default: break; } } // Erase the ghost from the given position void erase(int xCoordinate, int yCoordinate) { int x1 = xCoordinate - 3; int x2 = xCoordinate + 3; int y1 = yCoordinate - 3; int y2 = yCoordinate + 3; uLCD.filled_rectangle(x1, y1, x2, y2, BLACK); } // Move the ghost right void moveRight() { // If the space to the right is a valid position and is not the rightmost space if ((stage.positions[x + 1][y] != 0) && (x != 124)) { // The ghost is mobile immobile = false; // Erase the ghost from its current position erase(x, y); // Increment the ghost's x-coordinate x++; // If passed over a pac dot if (stage.positions[x - 4][y] == 2) { // Redraw the pac dot uLCD.pixel(x - 4, y, YELLOW); // If passed over a big pac dot } else { // Redraw the big pac dot for (int i = x - 2; i >= x - 5; i--) { if (stage.positions[i][y] == 3) { uLCD.filled_circle(i, y, 1, YELLOW); } } } // Draw the ghost in its new position draw(x, y); // If the space to the right is not a valid positions } else if (stage.positions[x + 1][y] == 0) { // The ghost is immobile immobile = true; wait(0.03); } // If the rightmost position is reached if (x == 124) { // The ghost is mobile immobile = false; // Erase the ghost from its current position erase(x, y); // Set the ghost's x-coordinate to 4 x = 4; // If passed over a pac dot if (stage.positions[124][68] == 2) { // Redraw the pac dot uLCD.pixel(124, 68, YELLOW); } // Draw the ghost in its new position draw(x, y); } // If Pac-Man's invincibility status changed if (pacman.powerUpChanged == true) { // Change the color of the ghost draw(x, y); // Reset Pac-Man's invincibility status change pacman.powerUpChanged = false; } // Set the ghost's next direction switch (nextDirection) { case FACEDOWN: if (stage.positions[x][y + 1] != 0) { direction = nextDirection; } break; case FACELEFT: if (stage.positions[x - 1][y] != 0) { direction = nextDirection; } break; case FACEUP: if (stage.positions[x][y - 1] != 0) { direction = nextDirection; } break; default: break; } } // Move the ghost down void moveDown() { // If the space in the downward direction is a valid position if (stage.positions[x][y + 1] != 0) { // The ghost is mobile immobile = false; // Erase the ghost from its current position erase(x, y); // Increment the ghost's y-coordinate y++; // If passed over a pac dot if (stage.positions[x][y - 4] == 2) { // Redraw the pac dot uLCD.pixel(x, y - 4, YELLOW); // If passed over a big pac dot } else { // Redraw the big pac dot for (int j = y - 2; j >= y - 5; j--) { if (stage.positions[x][j] == 3) { uLCD.filled_circle(x, j, 1, YELLOW); } } } // Draw the ghost in its new position draw(x, y); // If the space in the downward direction is not a valid position } else { // The ghost is immobile immobile = true; wait(0.03); } // If Pac-Man's invincibility status changed if (pacman.powerUpChanged == true) { // Change the color of the ghost draw(x, y); // Reset Pac-Man's invincibility status change pacman.powerUpChanged = false; } // Set the ghost's next direction switch (nextDirection) { case FACERIGHT: if (stage.positions[x + 1][y] != 0) { direction = nextDirection; } break; case FACELEFT: if (stage.positions[x - 1][y] != 0) { direction = nextDirection; } break; case FACEUP: if (stage.positions[x][y - 1] != 0) { direction = nextDirection; } break; default: break; } } // Move the ghost left void moveLeft() { // If the space to the left is a valid position and is not the leftmost space if ((stage.positions[x - 1][y] != 0) && (x != 4)) { // The ghost is mobile immobile = false; // Erase the ghost from its current position erase(x, y); // Decrement the ghost's x-coordinate x--; // If passed over a pac dot if (stage.positions[x + 4][y] == 2) { // Redraw the pac dot uLCD.pixel(x + 4, y, YELLOW); // If passed over a big pac dot } else { // Redraw the big pac dot for (int i = x + 2; i <= x + 5; i++) { if (stage.positions[i][y] == 3) { uLCD.filled_circle(i, y, 1, YELLOW); } } } // Draw the ghost in its new position draw(x, y); // If the space to the left is not a valid position } else if (stage.positions[x - 1][y] == 0) { // The ghost is immobile immobile = true; wait(0.03); } // If the leftmost position is reached if (x == 4) { // The ghost is mobile immobile = false; // Erase the ghost from its current position erase(x, y); // Set the ghost's x-coordinate to 124 x = 124; // If passed over a pac dot if (stage.positions[4][68] == 2) { // Redraw the pac dot uLCD.pixel(4, 68, YELLOW); } // Draw the ghost in its new position draw(x, y); } // If Pac-Man's invincibility status changed if (pacman.powerUpChanged == true) { // Change the color of the ghost draw(x, y); // Reset Pac-Man's invincibility status change pacman.powerUpChanged = false; } // Set the ghost's next direction switch (nextDirection) { case FACERIGHT: if (stage.positions[x + 1][y] != 0) { direction = nextDirection; } break; case FACEDOWN: if (stage.positions[x][y + 1] != 0) { direction = nextDirection; } break; case FACEUP: if (stage.positions[x][y - 1] != 0) { direction = nextDirection; } break; default: break; } } // Move the ghost up void moveUp() { // If the space in the upward direction is a valid position if (stage.positions[x][y - 1] != 0) { // The ghost is mobile immobile = false; // Erase the ghost from its current position erase(x, y); // Decrement the ghost's y-coordinate y--; // If passed over a pac dot if (stage.positions[x][y + 4] == 2) { // Redraw the pac dot uLCD.pixel(x, y + 4, YELLOW); // If passed over a big pac dot } else { // Redraw the big pac dot for (int j = y + 2; j <= y + 5; j++) { if (stage.positions[x][j] == 3) { uLCD.filled_circle(x, j, 1, YELLOW); } } } // Draw the ghost in its new position draw(x, y); // If the space in the upward direction is not a valid position } else { // The ghost is immobile immobile = true; wait(0.03); } // If Pac-Man's invincibility status changed if (pacman.powerUpChanged == true) { // Change the color of the ghost draw(x, y); // Reset Pac-Man's invincibility status change pacman.powerUpChanged = false; } // Set the ghost's next direction switch (nextDirection) { case FACERIGHT: if (stage.positions[x + 1][y] != 0) { direction = nextDirection; } break; case FACEDOWN: if (stage.positions[x][y + 1] != 0) { direction = nextDirection; } break; case FACELEFT: if (stage.positions[x - 1][y] != 0) { direction = nextDirection; } break; default: break; } } };