This program simulates a game of Pac-Man that allows for multiplayer. One player controls Pac-Man, while two other players control a red and yellow ghost using different tactile switches.

Dependencies:   4DGL-uLCD-SE PinDetect mbed

Fork of Pac-Man by Eric Xu

main.cpp

Committer:
soapy12312
Date:
2015-10-19
Revision:
1:839f59c6d021
Parent:
0:8b6686f2d4be

File content as of revision 1:839f59c6d021:

/*******************************************************
 * Author: Yuanzhe Xu
 * Institution: Georgia Institute of Technology
 * Date: October 18, 2015
 *
 * This main program simulates a game of Pac-Man that
 * allows for multiplayer. One player controls Pac-Man,
 * while two other players control a red and yellow
 * ghost using different tactile switches. Pac-Man
 * starts with three lives, and the ghosts have
 * infinite lives. Pac-Man's objective is to eat all of
 * the pac dots before running out of lives. Eating a
 * regular pac dot adds 10 points to Pac-Man's score;
 * eating a big pac dot adds 50 points to Pac-Man's
 * score. The ghosts' objective is to prevent Pac-Man
 * from doing so. If Pac-Man comes into contact with a
 * ghost, he dies and loses a life, causing Pac-Man and
 * both of the ghosts to reset. If Pac-Man runs out of 
 * lives, he loses the game. As a countermeasure to the
 * ghosts, the big pac dots are used as power-ups. The
 * power-ups allow Pac-Man to be invincible for a fixed
 * amount of time, during which Pac-Man can also eat the
 * ghosts and force them to reset to their starting
 * position. During each power-up period, the first
 * ghost Pac-Man eats adds 200 points to Pac-Man's
 * score, the second adds 400 points, the third adds 600
 * points, and so on. The ghosts have two movement
 * constraints: they must be moving at all times and
 * they cannot move backwards in the direction they came
 * (for example, when a ghost is moving to the right, it
 * cannot change directions and move to the left).
 * Failure to comply to the mobility constraint causes
 * the ghost to reset to its original starting position. 
 * When the game ends (Pac-Man completes his objective
 * or runs out of lives), a final screen is displayed
 * saying whether Pac-Man wins or loses and prints out
 * Pac-Man's final score.
 *******************************************************/

#include "mbed.h"
#include "uLCD_4DGL.h"
#include "PinDetect.h"
#include "Stage.h"
#include "Pacman.h"
#include "Ghost.h"

// Pac-Man controller
PinDetect PacmanRight(p9);
PinDetect PacmanDown(p10);
PinDetect PacmanLeft(p11);
PinDetect PacmanClick(p12);
PinDetect PacmanUp(p13);

// Red ghost controller
PinDetect redGhostRight(p14);
PinDetect redGhostDown(p15);
PinDetect redGhostLeft(p16);
PinDetect redGhostClick(p17);
PinDetect redGhostUp(p19);

// Yellow ghost controller
PinDetect yellowGhostRight(p25);
PinDetect yellowGhostDown(p24);
PinDetect yellowGhostLeft(p23);
PinDetect yellowGhostClick(p22);
PinDetect yellowGhostUp(p21);

// uLCD display
uLCD_4DGL uLCD(p28, p27, p30);


// Direction inputs
int volatile nextPacmanDirection = FACEUP;
int volatile nextRedGhostDirection = FACELEFT;
int volatile nextYellowGhostDirection = FACERIGHT;


// Set the next Pac-Man direction to be right
void PacmanRightTrigger() {
    nextPacmanDirection = FACERIGHT;
}

// Set the next Pac-Man direction to be down
void PacmanDownTrigger() {
    nextPacmanDirection = FACEDOWN;
}

// Set the next Pac-Man direction to be left
void PacmanLeftTrigger() {
    nextPacmanDirection = FACELEFT;
}

// Resume/Pause the game
void PacmanClickTrigger() {
    wait(0.5);

    while (PacmanClick == 1) {
    }
}

// Set the next Pac-Man direction to be up
void PacmanUpTrigger() {
    nextPacmanDirection = FACEUP;
}


// Set the next red ghost direction to be right
void redGhostRightTrigger() {
    nextRedGhostDirection = FACERIGHT;
}

// Set the next red ghost direction to be down
void redGhostDownTrigger() {
    nextRedGhostDirection = FACEDOWN;
}

// Set the next red ghost direction to be left
void redGhostLeftTrigger() {
    nextRedGhostDirection = FACELEFT;
}

// Resume/Pause the game
void redGhostClickTrigger() {
    wait(0.5);

    while (redGhostClick == 1) {
    }
}

// Set the next red ghost direction to be up
void redGhostUpTrigger() {
    nextRedGhostDirection = FACEUP;
}


// Move the yellow ghost right
void yellowGhostRightTrigger() {
    nextYellowGhostDirection = FACERIGHT;
}

// Set the next yellow ghost direction to be down
void yellowGhostDownTrigger() {
    nextYellowGhostDirection = FACEDOWN;
}

// Set the next yellow ghost direction to be left
void yellowGhostLeftTrigger() {
    nextYellowGhostDirection = FACELEFT;
}

// Resume/Pause the game
void yellowGhostClickTrigger() {
    wait(0.5);

    while (yellowGhostClick == 1) {
    }
}

// Set the next yellow ghost direction to be up
void yellowGhostUpTrigger() {
    nextYellowGhostDirection = FACEUP;
}


int main() {
    // Maximize the baud rate
    uLCD.baudrate(3000000);

    // Use internal pullups
    PacmanRight.mode(PullUp);
    PacmanDown.mode(PullUp);
    PacmanLeft.mode(PullUp);
    PacmanClick.mode(PullUp);
    PacmanUp.mode(PullUp);
    redGhostRight.mode(PullUp);
    redGhostDown.mode(PullUp);
    redGhostLeft.mode(PullUp);
    redGhostClick.mode(PullUp);
    redGhostUp.mode(PullUp);
    yellowGhostRight.mode(PullUp);
    yellowGhostDown.mode(PullUp);
    yellowGhostLeft.mode(PullUp);
    yellowGhostClick.mode(PullUp);
    yellowGhostUp.mode(PullUp);
    wait(0.01);
    // Interrupt callback functions
    PacmanRight.attach_deasserted(&PacmanRightTrigger);
    PacmanDown.attach_deasserted(&PacmanDownTrigger);
    PacmanLeft.attach_deasserted(&PacmanLeftTrigger);
    PacmanClick.attach_deasserted(&PacmanClickTrigger);
    PacmanUp.attach_deasserted(&PacmanUpTrigger);
    redGhostRight.attach_deasserted(&redGhostRightTrigger);
    redGhostDown.attach_deasserted(&redGhostDownTrigger);
    redGhostLeft.attach_deasserted(&redGhostLeftTrigger);
    redGhostClick.attach_deasserted(&redGhostClickTrigger);
    redGhostUp.attach_deasserted(&redGhostUpTrigger);
    yellowGhostRight.attach_deasserted(&yellowGhostRightTrigger);
    yellowGhostDown.attach_deasserted(&yellowGhostDownTrigger);
    yellowGhostLeft.attach_deasserted(&yellowGhostLeftTrigger);
    yellowGhostClick.attach_deasserted(&yellowGhostClickTrigger);
    yellowGhostUp.attach_deasserted(&yellowGhostUpTrigger);
    // Set sampling frequency
    PacmanRight.setSampleFrequency();
    PacmanDown.setSampleFrequency();
    PacmanLeft.setSampleFrequency();
    PacmanClick.setSampleFrequency();
    PacmanUp.setSampleFrequency();
    redGhostRight.setSampleFrequency();
    redGhostDown.setSampleFrequency();
    redGhostLeft.setSampleFrequency();
    redGhostClick.setSampleFrequency();
    redGhostUp.setSampleFrequency();
    yellowGhostRight.setSampleFrequency();
    yellowGhostDown.setSampleFrequency();
    yellowGhostLeft.setSampleFrequency();
    yellowGhostClick.setSampleFrequency();
    yellowGhostUp.setSampleFrequency();

    // Set up the stage
    Stage stage(uLCD);
    stage.initialize();

    // Set up Pac-Man
    Pacman pacman(uLCD, stage);
    pacman.initialize();

    // Set up the red ghost
    Ghost redGhost(RED, uLCD, stage, pacman);
    redGhost.initialize(60, 60, nextRedGhostDirection);

    // Set up the yellow ghost
    Ghost yellowGhost(YELLOW, uLCD, stage, pacman);
    yellowGhost.initialize(68, 60, nextYellowGhostDirection);

    // Wait 3 seconds
    wait(3);

    // Checks to see whether the game is over
    bool gameOver;

    // Loop through the game
    while (1) {
        pacman.setNextDirection(nextPacmanDirection);
        pacman.displayStatus();
        gameOver = pacman.move();

        // If all pac dots are eaten or Pac-Man runs out of lives
        if (gameOver == true) {
            // Break out of the loop
            break;
        }

        redGhost.setNextDirection(nextRedGhostDirection);
        redGhost.move();

        yellowGhost.setNextDirection(nextYellowGhostDirection);
        yellowGhost.move();
    }

    // Game over display
    pacman.gameOver();
}