Multi-game multiplayer arcade gaming system meant for the red X when playing Super Tic-Tac-Toe.
Dependencies: uLCD_4DGL_SE PinDetect SDFileSystem mbed wave_player
Pacman.h
- Committer:
- soapy12312
- Date:
- 2015-12-04
- Revision:
- 2:d35fde2d82cd
- Parent:
- 0:218d3fb75950
File content as of revision 2:d35fde2d82cd:
/****************************************************** * This header program declares all the functions and * variables used by the Pac-Man player in Pac-Man. ******************************************************/ #define DIE "/sd/Die.wav" #define THEME "/sd/Theme.wav" // Pacman class class Pacman { public: // Pac-Man constructor Pacman(PinDetect &PacmanRight, PinDetect &PacmanDown, PinDetect &PacmanLeft, PinDetect &PacmanUp, Stage &stage, uLCD_4DGL &uLCD, wave_player &waver) : PacmanRight(PacmanRight), PacmanDown(PacmanDown), PacmanLeft(PacmanLeft), PacmanUp(PacmanUp), stage(stage), uLCD(uLCD), waver(waver) { // Use internal pullups PacmanRight.mode(PullUp); PacmanDown.mode(PullUp); PacmanLeft.mode(PullUp); PacmanUp.mode(PullUp); wait(0.01); // Interrupt callback functions PacmanRight.attach_deasserted(this, &Pacman::PacmanRightTrigger); PacmanDown.attach_deasserted(this, &Pacman::PacmanDownTrigger); PacmanLeft.attach_deasserted(this, &Pacman::PacmanLeftTrigger); PacmanUp.attach_deasserted(this, &Pacman::PacmanUpTrigger); wait(0.01); // Set sampling frequency PacmanRight.setSampleFrequency(); PacmanDown.setSampleFrequency(); PacmanLeft.setSampleFrequency(); PacmanUp.setSampleFrequency(); wait(1); } // Play a sound file void playSound(char *wav) { // Open sound file FILE *wave_file; wave_file = fopen(wav, "r"); // Play wav file waver.play(wave_file); // Close wav file fclose(wave_file); } // Initialize Pac-Man at the start of the game void initialize() { x = 64; y = 108; lives = 3; livesChanged = true; score = 0; scoreChanged = true; direction = FACEUP; mouthOpen = false; pacDotsEaten = 0; bigPacDotsEaten = 0; powerUp = 0; powerUpChanged = false; ghostsEaten = 0; dead = false; draw(x, y); displayStatus(); } // Display score and number of lives remaining void displayStatus() { // If the number of lives just changed if (livesChanged == true) { // Draw the corresponding number of lives switch (lives) { case 3: drawLives(56, 12); drawLives(64, 12); drawLives(72, 12); break; case 2: erase(72, 12); drawLives(56, 12); drawLives(64, 12); break; case 1: erase(56, 12); drawLives(64, 12); break; default: break; } // Reset livesChanged livesChanged = false; } // If the score just changed if (scoreChanged == true) { // Print the new score uLCD.locate(0, 1); uLCD.printf("%d", score); scoreChanged = false; } // Print the invincibility counter uLCD.locate(14, 1); if (powerUp == 100) { uLCD.printf("100"); } else if (powerUp >= 10) { uLCD.printf(" %d", powerUp); } else { uLCD.printf(" %d", powerUp); } } // Move Pac-Man and return whether the game is over bool move() { // If all the pac dots are eaten or Pac-Man is out of lives if (((pacDotsEaten == stage.pacDots) && (bigPacDotsEaten == stage.bigPacDots)) || (lives == 0)) { // Return true that the game is over and exit out of the function return true; } // If Pac-Man is not invincible if (powerUp == 0) { // Reset the ghosts eaten counter ghostsEaten = 0; } // If Pac-Man is invincible if (powerUp > 0) { // Decrement the invincibility counter powerUp--; // If invincibility just ended or just started if ((powerUp == 0) || (powerUp == 99)) { // Changes the color of the ghosts powerUpChanged = true; // If invincibility did not just end or did not just start } else { // Set powerUpChanged to false powerUpChanged = false; } } // Move Pac-Man in his current direction switch (direction) { case FACERIGHT: moveRight(); break; case FACEDOWN: moveDown(); break; case FACELEFT: moveLeft(); break; case FACEUP: moveUp(); break; default: break; } // Return false that the game is over return false; } // Game over void gameOver() { // If all the pac dots have been eaten if ((pacDotsEaten == stage.pacDots) && (bigPacDotsEaten == stage.bigPacDots)) { // Pac-Man wins win(); // If the number of lives is 0 } else if (lives == 0) { // Pac-Man loses lose(); } } private: PinDetect &PacmanRight; PinDetect &PacmanDown; PinDetect &PacmanLeft; PinDetect &PacmanUp; Stage &stage; uLCD_4DGL &uLCD; wave_player &waver; int x; int y; int direction; volatile int nextDirection; int lives; bool livesChanged; int score; bool scoreChanged; bool mouthOpen; int pacDotsEaten; int bigPacDotsEaten; int powerUp; bool powerUpChanged; int ghostsEaten; bool dead; friend class Ghost; // Set the next Pac-Man direction to be right void PacmanRightTrigger() { nextDirection = FACERIGHT; } // Set the next Pac-Man direction to be down void PacmanDownTrigger() { nextDirection = FACEDOWN; } // Set the next Pac-Man direction to be left void PacmanLeftTrigger() { nextDirection = FACELEFT; } // Set the next Pac-Man direction to be up void PacmanUpTrigger() { nextDirection = FACEUP; } // Draw the Pac-Man to display lives void drawLives(int xCoordinate, int yCoordinate) { uLCD.filled_circle(xCoordinate, yCoordinate, 3, YELLOW); int x1 = xCoordinate - 2; int x2 = xCoordinate - 3; int y1 = yCoordinate - 1; int y2 = yCoordinate + 1; uLCD.rectangle(x1, y1, x2, y2, BLACK); uLCD.pixel(xCoordinate, yCoordinate, BLACK); uLCD.pixel(xCoordinate - 1, yCoordinate, BLACK); } // Draw Pac-Man based on his direction void draw(int xCoordinate, int yCoordinate) { // If his mouth is closed if (mouthOpen == false) { // Draw Pac-Man with his mouth closed as a circle uLCD.filled_circle(xCoordinate, yCoordinate, 3, YELLOW); // If his mouth is open } else { // Draw Pac-Man with his mouth open based on his direction int x1; int x2; int y1; int y2; switch (direction) { case FACERIGHT: uLCD.filled_circle(xCoordinate, yCoordinate, 3, YELLOW); x1 = xCoordinate + 2; x2 = xCoordinate + 3; y1 = yCoordinate - 1; y2 = yCoordinate + 1; uLCD.rectangle(x1, y1, x2, y2, BLACK); uLCD.pixel(xCoordinate, yCoordinate, BLACK); uLCD.pixel(xCoordinate + 1, yCoordinate, BLACK); break; case FACEDOWN: uLCD.filled_circle(xCoordinate, yCoordinate, 3, YELLOW); x1 = xCoordinate - 1; x2 = xCoordinate + 1; y1 = yCoordinate + 2; y2 = yCoordinate + 3; uLCD.rectangle(x1, y1, x2, y2, BLACK); uLCD.pixel(xCoordinate, yCoordinate, BLACK); uLCD.pixel(xCoordinate, yCoordinate + 1, BLACK); break; case FACELEFT: uLCD.filled_circle(xCoordinate, yCoordinate, 3, YELLOW); x1 = xCoordinate - 2; x2 = xCoordinate - 3; y1 = yCoordinate - 1; y2 = yCoordinate + 1; uLCD.rectangle(x1, y1, x2, y2, BLACK); uLCD.pixel(xCoordinate, yCoordinate, BLACK); uLCD.pixel(xCoordinate - 1, yCoordinate, BLACK); break; case FACEUP: uLCD.filled_circle(xCoordinate, yCoordinate, 3, YELLOW); x1 = xCoordinate - 1; x2 = xCoordinate + 1; y1 = yCoordinate - 2; y2 = yCoordinate - 3; uLCD.rectangle(x1, y1, x2, y2, BLACK); uLCD.pixel(xCoordinate, yCoordinate, BLACK); uLCD.pixel(xCoordinate, yCoordinate - 1, BLACK); break; default: break; } } } // Erase Pac-Man from the given position void erase(int xCoordinate, int yCoordinate) { uLCD.filled_circle(xCoordinate, yCoordinate, 3, BLACK); } // Move Pac-Man right void moveRight() { // If the space to the right is a valid positions and is not the rightmost space if ((stage.positions[x + 1][y] != 0) && (x != 124)) { // Erase Pac-Man from his current position erase(x, y); // Increment Pac-Man's x-coordinate x++; // Draw Pac-Man in his new position draw(x, y); // Alternate Pac-Man's mouth for animation mouthOpen = !mouthOpen; // If Pac-Man passes partially across a big pac dot if (stage.positions[x - 5][y] == 3) { // Redraw the big pac dot part uLCD.pixel(x - 4, y, YELLOW); } // Loop through Pac-Man's 7-pixel diameter for (int i = x - 3; i <= x + 3; i++) { // If a pac dot is eaten if (stage.positions[i][y] == 2) { // Increment the number of pac dots eaten pacDotsEaten++; // Add 10 to the score score += 10; // Set the coordinates to represent only a valid position stage.positions[i][y] = 1; // Changes the score display scoreChanged = true; // If a big pac dot is eaten } else if (stage.positions[i][y] == 3) { // Erase the rest of the big pac dot uLCD.pixel(x + 4, y, BLACK); // Increment the number of big pac dots eaten bigPacDotsEaten++; // Add 50 to the score score += 50; // Set the coordinates to represent only a valid position stage.positions[i][y] = 1; // Set the invincibility counter to 100 powerUp = 100; // Changes the score display scoreChanged = true; } } // If the space to the right is not a valid position } else if (stage.positions[x + 1][y] == 0) { // Draw Pac-Man with his mouth open uLCD.rectangle(x + 2, y - 1, x + 3, y + 1, BLACK); uLCD.pixel(x, y, BLACK); uLCD.pixel(x + 1, y, BLACK); wait(0.001); } // If the rightmost space is reached if (x == 124) { // Erase Pac-Man from his current position erase(x, y); // Set Pac-Man's x-coordinate to 4 x = 4; // Draw Pac-Man in his new positions draw(x, y); } // Set Pac-Man'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 Pac-Man down void moveDown() { // If the space in the downward direction is a valid position if (stage.positions[x][y + 1] != 0) { // Erase Pac-Man from his current position erase(x, y); // Increment Pac-Man's y-coordinate y++; // Draw Pac-Man in his new position draw(x, y); // Alternate Pac-Man's mouth for animation mouthOpen = !mouthOpen; // If Pac-Man passes partially through a big pac dot if (stage.positions[x][y - 5] == 3) { // Redraw the big pac dot part uLCD.pixel(x, y - 4, YELLOW); } // Loop through Pac-Man's 7-pixel diameter for (int j = y - 3; j <= y + 3; j++) { // If a pac dot is eaten if (stage.positions[x][j] == 2) { // Increment the number of pac dots eaten pacDotsEaten++; // Add 10 to the score score += 10; // Set the position to represent only a valid position stage.positions[x][j] = 1; // Changes the score display scoreChanged = true; // If a big pac dot is eaten } else if (stage.positions[x][j] == 3) { // Erase the rest of the big pac dot uLCD.pixel(x, y + 4, BLACK); // Increment the number of big pac dots eaten bigPacDotsEaten++; // Add 50 to the score score += 50; // Set the coordinates to represent only a valid position(1) stage.positions[x][j] = 1; // Set the invincibility counter to 100 powerUp = 100; // Changes the score display scoreChanged = true; } } // If the space in the downward direction is not a valid position } else { // Draw Pac-Man with his mouth open uLCD.rectangle(x - 1, y + 2, x + 1, y + 3, BLACK); uLCD.pixel(x, y, BLACK); uLCD.pixel(x, y + 1, BLACK); wait(0.001); } // Set Pac-Man'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 Pac-Man 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)) { // Erase Pac-Man from his current position erase(x, y); // Decrement Pac-Man's x-coordinate x--; // Draw Pac-Man in his new position draw(x, y); // Alternate Pac-Man's mouth for animation mouthOpen = !mouthOpen; // If Pac-Man passes partially through a big pac dot if (stage.positions[x + 5][y] == 3) { // Redraw the big pac dot part uLCD.pixel(x + 4, y, YELLOW); } // Loop through Pac-Man's 7-pixel diameter for (int i = x + 3; i >= x - 3; i--) { // If a pac dot is eaten if (stage.positions[i][y] == 2) { // Increment the number of pac dots eaten pacDotsEaten++; // Add 10 to the score score += 10; // Set the coordinates to represent only a valid position stage.positions[i][y] = 1; // Changes the score display scoreChanged = true; // If a big pac dot is eaten } else if (stage.positions[i][y] == 3) { // Erase the rest of the big pac dot uLCD.pixel(x - 4, y, BLACK); // Increment the number of big pac dots eaten bigPacDotsEaten++; // Add 50 to the score score += 50; // Set the coordinates to represent only a valid position stage.positions[i][y] = 1; // Set the invincibility counter to 100 powerUp = 100; // Changes the score display scoreChanged = true; } } // If the space to the left is not a valid position } else if (stage.positions[x - 1][y] == 0) { // Draw Pac-Man with his mouth open uLCD.rectangle(x - 2, y - 1, x - 1, y + 1, BLACK); uLCD.pixel(x, y, BLACK); uLCD.pixel(x - 1, y, BLACK); wait(0.001); } // If the leftmost position is reached if (x == 4) { // Erase Pac-Man from his current position erase(x, y); // Set Pac-Man's x-coordinate to 124 x = 124; // Draw Pac-Man in his new position draw(x, y); } // Set Pac-Man'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 Pac-Man up void moveUp() { // If the space in the upward direction is a valid position if (stage.positions[x][y - 1] != 0) { // Erase Pac-Man from his current position erase(x, y); // Decrement Pac-Man's y-coordinate y--; // Draw Pac-Man in his new position draw(x, y); // Alternate Pac-Man's mouth for animation mouthOpen = !mouthOpen; // If Pac-Man passes partially through a big pac dot if (stage.positions[x][y + 5] == 3) { // Redraw the big pac dot part uLCD.pixel(x, y + 4, YELLOW); } // Loop through Pac-Man's 7-pixel diameter for (int j = y + 3; j >= y - 3; j--) { // If a pac dot is eaten if (stage.positions[x][j] == 2) { // Increment the number of pac dots eaten pacDotsEaten++; // Add 10 to the score score += 10; // Set the coordinates to represent only a valid position stage.positions[x][j] = 1; // Changes the score display scoreChanged = true; // If a big pac dot is eaten } else if (stage.positions[x][j] == 3) { // Erase the reset of the big pac dot uLCD.pixel(x, y - 4, BLACK); // Increment the number of big pac dots eaten bigPacDotsEaten++; // Add 50 to the score score += 50; // Set the coordinates to represent only a valid position stage.positions[x][j] = 1; // Set the invincibility counter to 100 powerUp = 100; // Changes the score display scoreChanged = true; } } // If the space in the upward direction is not a valid position } else { // Draw Pac-Man with his mouth open uLCD.rectangle(x - 1, y - 2, x + 1, y - 3, BLACK); uLCD.pixel(x, y, BLACK); uLCD.pixel(x, y - 1, BLACK); wait(0.001); } // Set Pac-Man'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; } } // Dying animation void dyingAnimation() { erase(x, y); draw(x, y); uLCD.rectangle(x - 1, y - 2, x + 1, y - 3, BLACK); uLCD.pixel(x, y, BLACK); uLCD.pixel(x, y - 1, BLACK); uLCD.pixel(x - 1, y, BLACK); uLCD.pixel(x - 1, y - 1, BLACK); uLCD.pixel(x - 2, y - 2, BLACK); uLCD.pixel(x + 1, y, BLACK); uLCD.pixel(x + 1, y - 1, BLACK); uLCD.pixel(x + 2, y - 2, BLACK); wait(0.15); uLCD.pixel(x - 2, y, BLACK); uLCD.pixel(x - 3, y, BLACK); uLCD.pixel(x - 2, y - 1, BLACK); uLCD.pixel(x - 3, y - 1, BLACK); uLCD.pixel(x + 2, y, BLACK); uLCD.pixel(x + 3, y, BLACK); uLCD.pixel(x + 2, y - 1, BLACK); uLCD.pixel(x + 3, y - 1, BLACK); wait(0.15); uLCD.pixel(x - 1, y + 1, BLACK); uLCD.pixel(x - 2, y + 1, BLACK); uLCD.pixel(x - 3, y + 1, BLACK); uLCD.pixel(x - 2, y + 2, BLACK); uLCD.pixel(x + 1, y + 1, BLACK); uLCD.pixel(x + 2, y + 1, BLACK); uLCD.pixel(x + 3, y + 1, BLACK); uLCD.pixel(x + 2, y + 2, BLACK); wait(0.15); uLCD.pixel(x - 1, y + 2, BLACK); uLCD.pixel(x - 1, y + 3, BLACK); uLCD.pixel(x + 1, y + 2, BLACK); uLCD.pixel(x + 1, y + 3, BLACK); wait(0.15); uLCD.pixel(x, y + 1, BLACK); uLCD.pixel(x, y + 2, BLACK); uLCD.pixel(x, y + 3, BLACK); wait(0.15); } // Reinitialize Pac-Man after losing a life void reinitialize() { // Set Pac-Man's x-coordinate to the starting point x = 64; // Set Pac-Man's y-coordinate to the starting point y = 108; // Redraw the pac dots on the stage stage.redrawPacDots(); // Changes the lives display livesChanged = true; // Draw Pac-Man at his starting point draw(x, y); // Display the lives and score counter displayStatus(); } // Pac-Man dies void die() { // Decrement the number of lives lives--; // Erase Pac-Man from his current position erase(x, y); // Reset Pac-Man's direction to be up direction = FACEUP; // Displays Pac-Man's dying animation dyingAnimation(); // Play dying sound playSound(DIE); // If the number of lives is 0 if (lives == 0) { // Break out of the function return; } // Reinitialize Pac-Man reinitialize(); } // Pac-Man wins void win() { uLCD.cls(); uLCD.filled_rectangle(0, 0, 127, 127, BLACK); uLCD.locate(3, 7); uLCD.printf("Pac-Man wins.\n"); uLCD.locate(3, 8); uLCD.printf("Score: %d", score); } // Pac-Man loses void lose() { uLCD.cls(); uLCD.filled_rectangle(0, 0, 127, 127, BLACK); uLCD.locate(2, 7); uLCD.printf("Pac-Man loses.\n"); uLCD.locate(3, 8); uLCD.printf("Score: %d", score); } };