FrameTrigger.java

       1  /**
           * PacMan for J2ME Devices
           * CS 327 - Design Project,   Fall 2002
           * University of Illinois,   Urbana-Champaign
           *
           * file: FrameTrigger.java
           * contact: Braden Kowitz
           * date: 11/24/02
           **/
          
          //----------------------------------------------------------------------------//
          
          import javax.microedition.lcdui.*;
          import javax.microedition.midlet.*;
          
          
          /**
           * This trigger is responsible for calling advanceFrame(   ) on a GrameCanvas
           * object.
           **/
      21  public class FrameTrigger extends Thread
          {
          
           /**
           * The GameCanvas where we call advanceFrame.
           **/
      27   GameCanvas game_;
          
           /**
           * Time is miliseconds between frames
           **/
           private int frameDelay_;
          
           /**
           * Value which is true if the thread is to be stopped.
           **/
           private boolean stopped;
          
           /**
           * Constructor
           * @param g Canvas for wich to trigger frame updates.
           * @param frameDelay time in MS between frame updates.
           **/
      44   public FrameTrigger(  GameCanvas g,   int frameDelay )
           {
           game_ = g;
           frameDelay_ = frameDelay;
           stopped = true;
           }
          
           /**
           * Stops the trigger from functioning.
           * (  stops execution of the thread )
           **/
      55   public void stopTrigger(   )
           { stopped = true; }
          
           /**
           * starts the trigger
           */
      61   public void startTrigger(   )
           { stopped = false; }
          
           /**
           * Starts the trigger running.
           * - To be called by the thead start(   ) function call.
           **/
      68   public void run(   )
           {
           //stopped=false; // having this might cause problems
           while (  !stopped )
           {
           game_.advanceFrame(   );
           try {
           sleep(  frameDelay_ );
           } catch (  InterruptedException ie ) {}
           }
           System.out.println(  "FrameTrigger Thread Stopped" );
           }
          
          }

GameBoard.java

       1  /**
           * PacMan for J2ME Devices
           * CS 327 - Design Project,   Fall 2002
           * University of Illinois,   Urbana-Champaign
           *
           * file: GameBoard.java
           * contact: Braden Kowitz
           * date: 11/24/02
           **/
          
          //----------------------------------------------------------------------------//
          
          import javax.microedition.lcdui.*;
          import java.util.Vector;
          
          /**
           * A gameborad consists of a vector of GridNodes,   and actors.
           **/
      19  public class GameBoard
          {
          
           //--------------------------//
           // ENUM
           //--------------------------//
          
           /**
           * Enum for a desired state
           **/
           public static final int ALIVE = 0;
           public static final int DEAD = 1;
          
           //--------------------------//
           // MEMBER VARIABLES
           //--------------------------//
          
           /**
           * A vector containing all of the GridNodes in this board.
           **/
      39   private Vector nodes_;
          
           /**
           * A vector containing all of the active GhostActors on this board.
           **/
      44   private Vector ghosts_;
          
           /**
           * The pacman for this board
           **/
      49   private PacmanActor pacman_;
          
           /**
           * The state of the GameBoard
           * - state can be : ALIVE,   DEAD
           **/
           private int state_;
          
           //--------------------------//
           // FUNCTIONS
           //--------------------------//
          
           /**
           * Simple constructor,   takes no parameters.
           **/
      64   public GameBoard(   )
           {
           nodes_ = new Vector(   );
           ghosts_ = new Vector(   );
           state_ = ALIVE;
           }
          
           /**
           * Adds a GridNode to this board.
           **/
      74   public void addGridNode(  GridNode n )
           {
           nodes_.addElement(  n );
           }
          
           /**
           * Paints the board by calling paint on all GridNodes,  
           * pacman,   and each ghost.
           * @param g Graphics object where drawing should take place.
           */
      84   public void paint(  Graphics g )
           {
           for (  int i=0; i<nodes_.size(   ); i++ )
           {
           GridNode n = (  GridNode ) nodes_.elementAt(  i );
           n.paint(  g );
           }
          
           pacman_.paint(  g );
          
           for (  int i=0; i<ghosts_.size(   ); i++ )
           {
           GhostActor ghost = (  GhostActor ) ghosts_.elementAt(  i );
           ghost.paint(  g );
          
           g.drawString(  Integer.toString(  pacman_.score_ ),   68,   65,   16|4 );
           g.drawString(  Integer.toString(  pacman_.getLivesLeft(   ) ),   58,   65,   16|4 );
           }
           }
          
           /**
           * advance all actors one frame:
           * @return true if pacman has enough lives otherwise false
           **/
     108   public boolean advanceFrame(   )
           {
           // and ghosts:
           for (  int i=0; i<ghosts_.size(   ); i++ )
           {
           GhostActor ghost = (  GhostActor ) ghosts_.elementAt(  i );
          
           //March 18,   2003
           //Moved .advanceframe functions to try to get killing correct
           // (  when pacman and ghost are in the same node,   visually ) codewise this is correct.
           //if we use .getNode(   ),   pacman gets killed before we see the ghost touch him
           //if (  ghost.getNode(   ) == pacman_.getNode(   ) )
          
           if (  (  Math.abs(  ghost.getX(   ) - pacman_.getX(   ) ) < 3 ) && (  Math.abs(  ghost.getY(   ) - pacman_.getY(   ) ) < 3 ) )
           {
           if(  pacman_.isInvincible(   ) == false )
           {
           state_ = DEAD;
          
           }
           else
           {
           pacman_.score_+=5;
           ghost.restart(   );
           }
          
           }
          
           ghost.advanceFrame(   );
          
           }
          
           if (  state_ == DEAD )
           {
           pacman_.restart(   );
           if (  pacman_.getLivesLeft(   ) < 0 )
           return false;
           state_ = ALIVE;
          
           for (  int i=0; i<ghosts_.size(   ); i++ )
           {
           GhostActor ghost = (  GhostActor ) ghosts_.elementAt(  i );
           ghost.restart(   );
           }
          
           }
           else //If he's not dead,   then he can still move
           pacman_.advanceFrame(   );
          
           return true;
           }
          
           /**
           * @param p the PacmanActor for this board
           **/
     163   public void setPacman(  PacmanActor p )
           {
           pacman_ = p;
           }
          
           /**
           * @return the PacmanActor for this board
           **/
     171   public PacmanActor getPacman(   )
           {
           return pacman_;
           }
          
           /**
           * Adds a GhostActor to this board.
           * @param ghost the ghost to add.
           **/
     180   public void addGhost(  GhostActor ghost )
           {
           ghosts_.addElement(  ghost );
           }
          }
          

GameBoardFactory.java

       1  /**
           * PacMan for J2ME Devices
           * CS 327 - Design Project,   Fall 2002
           * University of Illinois,   Urbana-Champaign
           *
           * file: GameBoardFactory.java
           * contact: Braden Kowitz
           * date: 11/24/02
           **/
          
          //----------------------------------------------------------------------------//
          
          /**
           * Partial implementation of a Factory object to create GameBoard objects.
           **/
      16  public class GameBoardFactory
          {
           /**
           * 2-D array of GridNode objects that represent the board
           **/
      21   private static GridNode nodes[][];
          
           /**
           * Creates a sample board
           **/
      26   public static GameBoard test(   )
           {
          
          
           GridNode.setSize(  13 );
          
           GameBoard gb = new GameBoard(   );
          
           int size = 8;
           nodes = new GridNode[size][size-2];
          
           for (  int i=0; i<size; i++ ) {
           for (  int j=0; j<size-2; j++ )
           {
           nodes[i][j] = new GridNode(  i,  j );
           gb.addGridNode(  nodes[i][j] );
          
           } }
          
          
           // here we define our board:
          
           PacmanActor pac = new PacmanActor(  nodes[4][3] );
           gb.setPacman(  pac );
          
           GhostActor ghost;
           ghost = new GhostActor(  nodes[0][0],  pac );
           gb.addGhost(  ghost );
           ghost = new GhostActor(  nodes[0][5],  pac );
           gb.addGhost(  ghost );
           ghost = new GhostActor(  nodes[7][0],  pac );
           gb.addGhost(  ghost );
          
           nodes[0][0].setPellet(  GridNode.BIG_PELLET );
           nodes[0][5].setPellet(  GridNode.BIG_PELLET );
           nodes[7][0].setPellet(  GridNode.BIG_PELLET );
           nodes[7][5].setPellet(  GridNode.BIG_PELLET );
          
           UDLink(  1,  1,  1,  2 );
           UDLink(  1,  2,  1,  3 );
           UDLink(  1,  3,  1,  4 );
           UDLink(  1,  4,  1,  5 );
           UDLink(  1,  5,  1,  6 );
           UDLink(  2,  2,  2,  3 );
           UDLink(  2,  3,  2,  4 );
           UDLink(  2,  4,  2,  5 );
           UDLink(  3,  2,  3,  3 );
           UDLink(  3,  4,  3,  5 );
           UDLink(  4,  1,  4,  2 );
           UDLink(  4,  5,  4,  6 );
           UDLink(  5,  1,  5,  2 );
           UDLink(  5,  5,  5,  6 );
           UDLink(  6,  2,  6,  3 );
           UDLink(  6,  4,  6,  5 );
           UDLink(  7,  2,  7,  3 );
           UDLink(  7,  3,  7,  4 );
           UDLink(  7,  4,  7,  5 );
           UDLink(  8,  1,  8,  2 );
           UDLink(  8,  2,  8,  3 );
           UDLink(  8,  3,  8,  4 );
           UDLink(  8,  4,  8,  5 );
           UDLink(  8,  5,  8,  6 );
          
           LRLink(  1,  1,  2,  1 );
           LRLink(  2,  1,  3,  1 );
           LRLink(  3,  1,  4,  1 );
           LRLink(  4,  1,  5,  1 );
           LRLink(  5,  1,  6,  1 );
           LRLink(  6,  1,  7,  1 );
           LRLink(  7,  1,  8,  1 );
           LRLink(  1,  2,  2,  2 );
           LRLink(  3,  2,  4,  2 );
           LRLink(  5,  2,  6,  2 );
           LRLink(  7,  2,  8,  2 );
           LRLink(  2,  3,  3,  3 );
           LRLink(  3,  3,  4,  3 );
           LRLink(  4,  3,  5,  3 );
           LRLink(  5,  3,  6,  3 );
           LRLink(  6,  3,  7,  3 );
           LRLink(  2,  4,  3,  4 );
           LRLink(  3,  4,  4,  4 );
           LRLink(  4,  4,  5,  4 );
           LRLink(  5,  4,  6,  4 );
           LRLink(  6,  4,  7,  4 );
           LRLink(  1,  5,  2,  5 );
           LRLink(  3,  5,  4,  5 );
           LRLink(  5,  5,  6,  5 );
           LRLink(  7,  5,  8,  5 );
           LRLink(  1,  6,  2,  6 );
           LRLink(  2,  6,  3,  6 );
           LRLink(  3,  6,  4,  6 );
           LRLink(  4,  6,  5,  6 );
           LRLink(  5,  6,  6,  6 );
           LRLink(  6,  6,  7,  6 );
           LRLink(  7,  6,  8,  6 );
          
          
           return gb;
           }
          
           /**
           * Creates a up-down link in the nodes[][] array.
           * - Upper left is (  1,  1 )
           **/
     130   private static void UDLink(  int x1,   int y1,   int x2,   int y2 )
           {
           nodes[x1-1][y1-1].setDown(  nodes[x2-1][y2-1] );
           nodes[x2-1][y2-1].setUp(  nodes[x1-1][y1-1] );
           }
           /**
           * Creates a left-right link in the nodes[][] array.
           * - Upper left is (  1,  1 )
           **/
     139   private static void LRLink(  int x1,   int y1,   int x2,   int y2 )
           {
           nodes[x1-1][y1-1].setRight(  nodes[x2-1][y2-1] );
           nodes[x2-1][y2-1].setLeft(  nodes[x1-1][y1-1] );
           }
          }
          
          //----------------------------------------------------------------------------//

GameCanvas.java

       1  /**
           * PacMan for J2ME Devices
           * CS 327 - Design Project,   Fall 2002
           * University of Illinois,   Urbana-Champaign
           *
           * file: GameCanvas.java
           * contact: Braden Kowitz
           * date: 11/24/02
           **/
          
          //----------------------------------------------------------------------------//
          
          import javax.microedition.lcdui.*;
          
          /**
           * This class is derived from a MIDlet canvas.
           * It contains the main functionality of the game.
           * It does three things basically
           * -# Contains A GameBoard,   which contains the game primitives and drawing code.
           * -# Runs a FrameTrigger,   which spawns a thread to periodically
           * update the frames.
           * -# Listens for key-presses,   and notifies apropriate objects in the gameboard.
           **/
      24  public class GameCanvas extends Canvas implements CommandListener
          {
          
           /**
           * The game board contains the game primitives,   logic,   and drawing code.
           * This object is created during construction.
           **/
      31   GameBoard gameBoard_;
          
           /**
           * frameTrigger object is responsible for periodically calling back to
           * this object to trigger a frame update.
           **/
      37   FrameTrigger frameTrigger_;
          
      39   private final pacman midlet;
      40   private final Command exitCommand;
      41   private final Command menuCommand;
          
           /**
           * Constructor.
           * @param disp The display where the game should run.
           **/
      47   public GameCanvas(  pacman midlet )
           {
           this.midlet = midlet;
          
           exitCommand = new Command(  "Exit",   Command.EXIT,   1 );
           menuCommand = new Command(  "Menu",   Command.SCREEN,   1 );
           addCommand(  exitCommand );
           addCommand(  menuCommand );
           setCommandListener(  this );
          
           gameBoard_ = GameBoardFactory.test(   );
           frameTrigger_ = new FrameTrigger(  this,   20 );
           frameTrigger_.start(   );
           frameTrigger_.startTrigger(   );
           }
          
      63   public void unPause(   )
           {
           frameTrigger_ = new FrameTrigger(  this,   20 );
           frameTrigger_.start(   );
           frameTrigger_.startTrigger(   );
           }
          
           /**
           * Called by the system to repaint the screen.
           * @param g Graphics object where drawing should take place.
           **/
      74   protected void paint(  Graphics g )
           {
           // clear the screen:
           g.setColor(  255,  255,  255 );
           g.fillRect(  0,  0,  this.getWidth(   ),  this.getHeight(   ) );
          
           // draw the board
           gameBoard_.paint(  g );
           }
          
           /**
           * This function is called periodically by FrameTrigger.
           * It simply tells the gameboard to advance it's logic
           * by one frame,   then it requests a repaint from the system.
           **/
      89   public void advanceFrame(   )
           {
           if (  gameBoard_.advanceFrame(   ) )
           {
           midlet.gameOver =0;
           repaint(   );
           }
           else
           {
           frameTrigger_.stopTrigger(   );
           midlet.gameOver = 1;
           System.out.println(  "set gameover to 1" );
           midlet.menuScreen(   );
           }
           }
          
           /**
           * This function is called by the system when the user
           * presses a key.
           * @param keyCode The unique int value of the key being pressed'
           *
           * Modified: 3/4/03 : Paul Force
           * Changed to use a more general key binding. Should work
           * on any phone now
           **/
     114   protected void keyPressed(  int keyCode )
           {
           int action = getGameAction(  keyCode );
          
           switch (  action )
           {
           case UP:
           gameBoard_.getPacman(   ).setDesiredDirection(  
           PacmanActor.UP );
           break;
          
           case DOWN:
           gameBoard_.getPacman(   ).setDesiredDirection(  
           PacmanActor.DOWN );
           break;
          
           case LEFT:
           gameBoard_.getPacman(   ).setDesiredDirection(  
           PacmanActor.LEFT );
           break;
          
           case RIGHT:
           gameBoard_.getPacman(   ).setDesiredDirection(  
           PacmanActor.RIGHT );
           break;
           }
           }
          
           /**
           * Respond to a command issued on the canvas
           **/
     145   public void commandAction(  Command c,   Displayable s )
           {
           if (  c == exitCommand )
           {
           frameTrigger_.stopTrigger(   );
           midlet.quit(   );
           }
           if (  c == menuCommand )
           {
           frameTrigger_.stopTrigger(   );
           midlet.menuScreen(   );
           }
           }
          }
          
          //----------------------------------------------------------------------------//

GhostActor.java

       1  /**
           * PacMan for J2ME Devices
           * CS 327 - Design Project,   Fall 2002
           * University of Illinois,   Urbana-Champaign
           *
           * file: GhostActor.java
           * contact: Braden Kowitz
           * date: 11/24/02
           **/
          
          //----------------------------------------------------------------------------//
          
          import javax.microedition.lcdui.*;
          
          /**
           * Represents a ghost on the game board.
           **/
      18  public class GhostActor
          {
           //--------------------------//
           // ENUM
           //--------------------------//
          
           /**
           * Enum for a desired dirrection.
           **/
           public static final int NONE = 0;
           /**
           * Enum for a desired dirrection.
           **/
           public static final int UP = 1;
           /**
           * Enum for a desired dirrection.
           **/
           public static final int DOWN = 2;
           /**
           * Enum for a desired dirrection.
           **/
           public static final int LEFT = 3;
           /**
           * Enum for a desired dirrection.
           **/
           public static final int RIGHT = 4;
          
           //--------------------------//
           // MEMBER VARIABLES
           //--------------------------//
          
           /**
           * The node where this ghost currently resides
           **/
      52   private GridNode myNode_;
          
          
           /**
           * This is the start node and where the ghost goes back to if
           * pacman is killed
           **/
      59   private GridNode resetNode_;
          
           /**
           * The pacman which this ghost is chasing
           * (  or running from )
           **/
      65   private PacmanActor target_;
          
           /**
           * current X Pixel coord of this actor
           **/
           private int pixelX_;
          
           /**
           * current Y Pixel coord of this actor
           **/
           private int pixelY_;
          
           /**
           * destination X Pixel coord for this actor
           **/
           private int newPixelX_;
          
           /**
           * destination Y Pixel coord for this actor
           **/
           private int newPixelY_;
          
           /**
           * This value is true if the ghosts should run from pacman.
           **/
           private static boolean runFromPac_;
          
           //--------------------------//
           // FUNCTIONS
           //--------------------------//
          
           /**
           * Constructor for this GhostActor.
           * @param startingPosition the GridNode where this ghosts begins the game
           * @param target the PacmanActor this ghost should chase or run from.
           **/
     101   public GhostActor(  GridNode startingPosition,   PacmanActor target )
           {
           myNode_ = startingPosition;
           resetNode_ = startingPosition;
           target_ = target;
          
           pixelX_ = myNode_.pixelCenterX(   );
           pixelY_ = myNode_.pixelCenterY(   );
           newPixelX_ = pixelX_;
           newPixelY_ = pixelY_;
          
           }
          
           /**
           * Sets when all ghosts should run from pacman.
           **/
     117   public static void setRunFromPac(  boolean b )
           { runFromPac_ = b; }
          
           /**
           * Added by Benson Fung (  for killing pacman )
           * @return the current node where this ghost resides
           **/
     124   public GridNode getNode(   ) {
           return myNode_;
           }
          
           /**
           * Called to advance the logic of the game one frame.
           **/
     131   public void advanceFrame(   )
           {
           // if we are in an animation:
           if (  (  pixelX_ != newPixelX_ ) || (  pixelY_ != newPixelY_ ) )
           {
           // move closer to the destination:
           if (  pixelX_ < newPixelX_ ) pixelX_++;
           if (  pixelX_ > newPixelX_  ) pixelX_--;
           if (  pixelY_ < newPixelY_ ) pixelY_++;
           if (  pixelY_ > newPixelY_  ) pixelY_--;
           }
           else
           {
           // find out the XY for pacman:
           int pacX = target_.getNode(   ).pixelCenterX(   );
           int pacY = target_.getNode(   ).pixelCenterY(   );
          
           // calculate distance from current position
           pacX -= pixelX_;
           pacY -= pixelY_;
          
           System.out.println(  "(  " + pacX +",  " + pacY + " )" );
          
           // do some logic to pick directions:
           if (  Math.abs(  pacX ) > Math.abs(  pacY ) )
           {
           if (  pacX > 0 ) moveTowards(  RIGHT,  UP,  DOWN,  LEFT );
           else moveTowards(  LEFT,  DOWN,  UP,  RIGHT );
           }
           else
           {
           if (  pacY > 0 ) moveTowards(  DOWN,  LEFT,  RIGHT,  DOWN );
           else moveTowards(  UP,  RIGHT,  LEFT,  UP );
           }
          
           }
           }
          
           /**
           * Tries to move the ghost in these directions.
           * The first one is most favorable.
           * @param i1 First most desierable choice
           * @param i2 Second most desierable choice
           * @param i3 Third most desierable choice
           * @param i4 Fourth most desierable choice
           **/
     177   private void moveTowards(  int i1,   int i2,   int i3,   int i4 )
           {
           // if we're running from pacman,   we do these in the opposite order:
           if (  runFromPac_ )
           {
           if (   goInDirection(  i4 )  ) return;
           if (   goInDirection(  i3 )  ) return;
           if (   goInDirection(  i2 )  ) return;
           if (   goInDirection(  i1 )  ) return;
           }
           else
           {
           if (   goInDirection(  i1 )  ) return;
           if (   goInDirection(  i2 )  ) return;
           if (   goInDirection(  i3 )  ) return;
           if (   goInDirection(  i4 )  ) return;
           }
           }
          
           /**
           * Tries to start moving in the specified dirrection.
           * @param d desired dirrection in which to move
           * @return true if we can go in this dirrection
           **/
     201   private boolean goInDirection(  int d )
           {
           if (  d == LEFT ) return goToNode(  myNode_.getLeft(   ) );
           if (  d == RIGHT ) return goToNode(  myNode_.getRight(   ) );
           if (  d == UP ) return goToNode(  myNode_.getUp(   ) );
           if (  d == DOWN ) return goToNode(  myNode_.getDown(   ) );
           return false;
           }
          
           /**
           * @param n Goes to this node if it is not null
           * @return true when it's possible to go to the node
           **/
     214   private boolean goToNode(  GridNode n )
           {
           if (  n == null ) return false;
           myNode_ = n;
           newPixelX_ = myNode_.pixelCenterX(   );
           newPixelY_ = myNode_.pixelCenterY(   );
           return true;
           }
          
           /**
           * Paints the GhostActor
           * @param g Graphics object where drawing should take place.
           **/
     227   public void paint(  Graphics g )
           {
           g.setColor(  0,  0,  0 );
           g.drawArc(  pixelX_-4,  
           pixelY_-4,  
           8,  8,  
           0,  
           360 );
           }
          
           /**
           * Returns the current x coordinate of the ghost
           **/
     240   public int getX(   )
           {
           return pixelX_;
           }
          
           /**
           * Returns the current y coordinate of the ghost
           **/
     248   public int getY(   )
           {
           return pixelY_;
           }
          
          /*
          
          Restart function:
           Added 4-15-03 by Trevor Donarski
          
           When pacman dies,   this function will be called to move the ghosts to their initial
           positions. This will also ensure that if a ghost is on the start position when pacman
           dies,   he doesn't respawn exactly on top of the ghost and start a loop of infinite kills.
          
          */
          
     264   public void restart(   )
           {
           myNode_ = resetNode_;
           pixelX_ = resetNode_.pixelCenterX(   );
           pixelY_ = resetNode_.pixelCenterY(   );
           newPixelX_ = pixelX_;
           newPixelY_ = pixelY_;
          
           }
          
          
          
          }

GridNode.java

       1  /**
           * PacMan for J2ME Devices
           * CS 327 - Design Project,   Fall 2002
           * University of Illinois,   Urbana-Champaign
           *
           * file: GridNode.java
           * contact: Braden Kowitz
           * date: 11/24/02
           **/
          
          //----------------------------------------------------------------------------//
          
          import javax.microedition.lcdui.*;
          
          /**
           * Represents a cell on the gameboard.
           * Nodes can draw itself and also contain informaion on the node's contents
           **/
      19  public class GridNode
          {
          
           //--------------------------//
           // ENUM
           //--------------------------//
          
           //@{
          
           /**
           * Enum value for the pellet_ member.
           **/
           public static final int NO_PELLET = 0;
           /**
           * Enum value for the pellet_ member.
           * Small pellets are worth points.
           **/
           public static final int SMALL_PELLET = 1;
           /**
           * Enum value for the pellet_ member.
           * Large pellets make pacman eat ghosts for a set ammount of time.
           **/
           public static final int BIG_PELLET = 2;
          
           //@}
          
           //--------------------------//
           // GRID SIZE
           //--------------------------//
          
           /**
           * Defines the size of the grid squares.
           * Units are pixels.
           **/
           private static int size_;
          
           /**
           * @param i size in pixels for all GridNode objects
           **/
      58   public static void setSize(  int i )
           {
           size_ = i;
           }
          
           /**
           * @return The size in pixels for all GridNode objects
           **/
      66   public static int getSize(   )
           {
           return size_;
           }
          
           //--------------------------//
           // MEMBER VARIABLES
           //--------------------------//
          
           /**
           * Defines the type of pellet that is in the GridNode.
           * Valid values are
           * - NO_PELLET
           * - SMALL_PELLET
           * - BIG_PELLET
           **/
           private int pellet_;
          
           //@{
          
           /**
           * Pointer to the GridNode to the left of this one on the game board.
           * This value is null when there is no path for actors to move
           * to the left.
           **/
           private GridNode left_;
          
           /**
           * Pointer to the GridNode to the right of this one on the game board.
           * This value is null when there is no path for actors to move
           * to the right.
           **/
           private GridNode right_;
          
           /**
           * Pointer to the GridNode up from this one on the game board.
           * This value is null when there is no path for actors to move up.
           **/
           private GridNode up_;
          
           /**
           * Pointer to the GridNode down from this one on the game board.
           * This value is null when there is no path for actors to move down.
           **/
           private GridNode down_;
          
           //@}
          
           /**
           * Position of this GridNode in the X axis.
           * - These are grid co-ordinates,   not pixels.
           * - This is specified during object construction.
           **/
           private int posX_;
          
           /**
           * Position of this GridNode in the Y axis.
           * - These are grid co-ordinates,   not pixels.
           * - This is specified during object construction.
           **/
           private int posY_;
          
           //@{
          
           /**
           * X pixel coord of the Upper Left corner of this GridNode
           **/
           private int pixelULX_;
          
           /**
           * Y pixel coord of the Upper Left corner of this GridNode
           **/
           private int pixelULY_;
          
           /**
           * X pixel coord of the Lower Right corner of this GridNode
           **/
           private int pixelLRX_;
          
           /**
           * Y pixel coord of the Lower Right corner of this GridNode
           **/
           private int pixelLRY_;
          
           /**
           * X pixel coord of the Center of this GridNode
           **/
           private int pixelCX_;
          
           /**
           * Y pixel coord of the Center of this GridNode
           **/
           private int pixelCY_;
          
           //@}
          
           //--------------------------//
           // PUBLIC FUNCTIONS
           //--------------------------//
          
           /**
           * Constructor for a GridNode
           * - These are grid co-ordinates,   not pixels.
           * @param x Position of this GridNode in the X axis.
           * @param y Position of this GridNode in the Y axis.
           **/
     172   public GridNode(  int x,   int y )
           {
           posX_ = x;
           posY_ = y;
          
           left_ = null;
           right_ = null;
           up_ = null;
           down_ = null;
          
           pellet_ = SMALL_PELLET;
          
           //set the pixel positions:
           // upper left
           pixelULX_ = posX_ * size_;
           pixelULY_ = posY_ * size_;
           // lower right
           pixelLRX_ = pixelULX_ + size_ -1;
           pixelLRY_ = pixelULY_ + size_ -1;
           // center
           pixelCX_ = (  pixelULX_ + pixelLRX_ )/2;
           pixelCY_ = (  pixelULY_ + pixelLRY_ )/2;
           }
          
          
           /**
           * @return the X pixel coord of the Center of this GridNode
           **/
     200   public int pixelCenterX(   )
           {
           return pixelCX_;
           }
          
           /**
           * @return the X pixel coord of the Center of this GridNode
           **/
     208   public int pixelCenterY(   )
           {
           return pixelCY_;
           }
          
           //@{
          
           /**
           * Sets the pointer to the GridNode to the left of this one on the game board.
           * This value is null when there is no path for actors to move
           * to the left.
           *
           * @param n GridNode object or null
           **/
     222   public void setLeft(  GridNode n )
           {
           left_ = n;
           }
          
           /**
           * Sets the pointer to the GridNode to the right of this one on the game board.
           * This value is null when there is no path for actors to move
           * to the right.
           *
           * @param n GridNode object or null
           **/
     234   public void setRight(  GridNode n )
           {
           right_ = n;
           }
          
           /**
           * Sets the pointer to the GridNode up from this one on the game board.
           * This value is null when there is no path for actors to move up.
           *
           * @param n GridNode object or null
           **/
     245   public void setUp(  GridNode n )
           {
           up_ = n;
           }
          
           /**
           * Sets the pointer to the GridNode down from this one on the game board.
           * This value is null when there is no path for actors to move down.
           *
           * @param n GridNode object or null
           **/
     256   public void setDown(  GridNode n ) { down_ = n; }
          
           /**
           * Gets the pointer to the GridNode left from this one on the game board.
           * This value is null when there is no path for actors to move left.
           *
           * @return GridNode object or null
           **/
     264   public GridNode getLeft(   ) { return left_; }
          
           /**
           * Gets the pointer to the GridNode right from this one on the game board.
           * This value is null when there is no path for actors to move right.
           *
           * @return GridNode object or null
           **/
     272   public GridNode getRight(   ) { return right_; }
          
           /**
           * Gets the pointer to the GridNode up from this one on the game board.
           * This value is null when there is no path for actors to move up.
           *
           * @return GridNode object or null
           **/
     280   public GridNode getUp(   ) { return up_; }
          
           /**
           * Gets the pointer to the GridNode down from this one on the game board.
           * This value is null when there is no path for actors to move down.
           *
           * @return GridNode object or null
           **/
     288   public GridNode getDown(   ) { return down_; }
          
           //@}
          
           /**
           * Sets the type of pellet that is in this GridNode.
           * - Valid values are
           * - NO_PELLET
           * - SMALL_PELLET
           * - BIG_PELLET
           * @param i *_PELLET enum.
           */
     300   public void setPellet(  int i )
           {
           pellet_ = i;
           }
          
           /**
           * Returns the type of pellet that is in this GridNode.
           * - Valid values are
           * - NO_PELLET
           * - SMALL_PELLET
           * - BIG_PELLET
           * @return *_PELLET enum.
           */
     313   public int getPellet(   )
           {
           return pellet_;
           }
          
           /**
           * This function is responsible for painting the GridNode
           * @param g Graphics object where drawing should take place.
           **/
     322   public void paint(  Graphics g )
           {
           // clear the square
           g.setColor(  255,  255,  255 );
           g.fillRect(  pixelULX_,  pixelULY_,  pixelLRX_,  pixelLRY_ );
          
           // draw the borders:
           g.setColor(  0,  0,  0 );
           if (  left_ == null ) g.drawLine(  pixelULX_,  pixelULY_,  pixelULX_,  pixelLRY_ );
           if (  right_ == null ) g.drawLine(  pixelLRX_,  pixelULY_,  pixelLRX_,  pixelLRY_ );
           if (  up_ == null ) g.drawLine(  pixelULX_,  pixelULY_,  pixelLRX_,  pixelULY_ );
           if (  down_ == null ) g.drawLine(  pixelULX_,  pixelLRY_,  pixelLRX_,  pixelLRY_ );
          
           // draw the dots:
          
           int radius = 0;
           if (  pellet_ == BIG_PELLET )
           radius = size_ / 3;
           if (  pellet_ == SMALL_PELLET )
           radius = size_ / 5;
           if (  pellet_ != NO_PELLET )
           g.fillArc(  pixelCX_,  pixelCY_,  radius,  radius,  0,  360 );
          
           }
          
          }

MenuScreen.java

       1  import javax.microedition.midlet.*;
          import javax.microedition.lcdui.*;
          import javax.microedition.io.*;
          
       5  public class MenuScreen
       6   extends List
       7   implements CommandListener
          {
       9   private final pacman midlet;
      10   private final Command quitCommand;
      11   private final String NEW_TEXT = "New Game";
      12   private final String CONTINUE_TEXT = "Continue";
          
      14   public MenuScreen(  pacman midlet )
           {
           super(  "PacMan",   List.IMPLICIT );
          
           this.midlet = midlet;
          
           append(  NEW_TEXT,   null );
           if (  !(  midlet.gameOver == 1 ) )
           {
           append(  CONTINUE_TEXT,   null );
           }
          
           quitCommand = new Command(  "Quit",   Command.EXIT,   2 );
           addCommand(  quitCommand );
           setCommandListener(  this );
           }
          
      31   public void commandAction(  Command c,   Displayable d )
           {
           if (  c == List.SELECT_COMMAND )
           {
           if (  getString(  getSelectedIndex(   ) ).equals(  NEW_TEXT ) )
           {
           try
           {
           midlet.restartApp(   );
           }
           catch (  javax.microedition.midlet.MIDletStateChangeException midException )
           {
           midException.printStackTrace(   );
           System.exit(  1 );
           }
           }
           if (  getString(  getSelectedIndex(   ) ).equals(  CONTINUE_TEXT ) )
           {
           midlet.continueGame(   );
           }
           }
           else // quit command
           {
           midlet.quit(   );
           }
           }

PacmanActor.java

       1  /**
           * PacMan for J2ME Devices
           * CS 327 - Design Project,   Fall 2002
           * CS 329 - Design Project,   Spring 2003
           * University of Illinois,   Urbana-Champaign
           *
           * file: PacmanActor.java
           * contact: Trevor Donarski
           * date: 02/01/03
           **/
          
          //----------------------------------------------------------------------------//
          
          import javax.microedition.lcdui.*;
          import java.util.Timer;
          import java.util.TimerTask;
          
          /**
           * Represents pacman on the game board.
           **/
      21  public class PacmanActor
          {
           //--------------------------//
           // ENUM
           //--------------------------//
          
           /**
           * Enum for a desired dirrection.
           **/
           public static final int NONE = 0;
           /**
           * Enum for a desired dirrection.
           **/
           public static final int UP = 1;
           /**
           * Enum for a desired dirrection.
           **/
           public static final int DOWN = 2;
           /**
           * Enum for a desired dirrection.
           **/
           public static final int LEFT = 3;
           /**
           * Enum for a desired dirrection.
           **/
           public static final int RIGHT = 4;
          
           //--------------------------//
           // MEMBER VARIABLES
           //--------------------------//
          
           /**
           * The node where pacman currently resides
           **/
      55   private GridNode myNode_;
          
           /**
           * The number of small pellets that pacman has eaten this game.
           * This helps us calculate the score.
           **/
           private int pelletsEaten_;
          
           /**
           * Keeps track of pacman's current score.
           */
           public int score_;
          
           /**
           * This is the invincibility variable... If pacman is invincible he'll eat the ghost :o )
           **/
           public boolean invincible_;
          
          
           /**
           * current X Pixel coord of this actor
           **/
           private int pixelX_;
          
           /**
           * current Y Pixel coord of this actor
           **/
           private int pixelY_;
          
           /**
           * destination X Pixel coord for this actor
           **/
           private int newPixelX_;
          
           /**
           * destination Y Pixel coord for this actor
           **/
           private int newPixelY_;
          
           /**
           * Desired dirrecton where pacman should move.
           * This is specified by user actions (  pressing movment keys )
           **/
           private int direction_;
          
           /**
           * NEW Apr. 3,   2003 - PDF
           * - addresses the problem with pacman moonwalking
           *
           * Direction PacMan is currently moving
           **/
           private int animDirection_ = RIGHT;
          
           /**
           * The Node where pacman starts
           **/
     111   private GridNode startNode_;
          
           /**
           * NEW Feb. 25,   2003
           * Added By Benson Fung
           *
           * This helps speed up calculations for the mouth angle
           */
           //Lags the controls
           //private int currentDirection_;
          
           /**
           * The current angle of the opening of pacman's mouth
           **/
           private int mouthAngle_;
          
           /**
           * The amount and dirrection of change that the mouth will
           * Take in the next frame.
           **/
           private int mouthAngleChange_;
          
           /**
           * Specifies startAngle in fillARc depending on
           * direction pacman is facing
           */
           private int mouthAngleDirection_;
          
           /**
           * New April 15th,   2003
           * Implements Lives
           */
           private int myLivesLeft_;
          
           /**
           * New April 28th,   2003
           * Implements Invinciblity
           */
     149   private PacmanTimer invincibleTimer;
          
           //--------------------------//
           // FUNCTIONS
           //--------------------------//
          
           /**
           * Constructor for this PacmanActor.
           * @param startingPosition the GridNode where this ghosts begins the game
           **/
     159   public PacmanActor(  GridNode startingPosition )
           {
           myNode_ = startingPosition;
           startNode_ = startingPosition;
           invincible_ = false;
          
           pixelX_ = myNode_.pixelCenterX(   );
           pixelY_ = myNode_.pixelCenterY(   );
           newPixelX_ = pixelX_;
           newPixelY_ = pixelY_;
          
           direction_ = NONE;
           //currentDirection_ = direction_;
          
           /*
           myNode_ = startingPosition;
           startNode_ = startingPosition;
          
           pixelX_ = myNode_.pixelCenterX(   );
           pixelY_ = myNode_.pixelCenterY(   );
           newPixelX_ = pixelX_;
           newPixelY_ = pixelY_;
          
           direction_ = NONE;
           //currentDirection_ = direction_;
           */
          
           pelletsEaten_ = 0;
          
           // mouthAngle starts Pacman facing right
           mouthAngleDirection_ = 20;
           // 40 degree arc mouth opening
           mouthAngle_ = 320;
           mouthAngleChange_ = +10;
          
           //Number of lives left
           myLivesLeft_ = 2;
           }
          
           /**
           * @return the current node where pacman resides
           **/
     201   public GridNode getNode(   ) {
           return myNode_;
           }
          
           /**
           * @return the number of small pellets that pacman has eaten in this game.
           **/
     208   public int getPelletsEaten(   )
           {
           return pelletsEaten_;
           }
          
           /**
           * @return Pacman's current x coordinate
           */
     216   public int getX(   )
           {
           return pixelX_;
           }
          
           /**
           * @return Pacman's current y coordinate
           */
     224   public int getY(   )
           {
           return pixelY_;
           }
          
           /**
           * @return Number of lives pacman has left. If < 0,   then game is over
           */
     232   public int getLivesLeft(   )
           {
           return myLivesLeft_;
           }
          
           /**
           * Sets the dirrection the user wishes pacman to move.
           * @param d enum: NONE,   RIGHT,   LEFT,   UP,   DOWN
           **/
     241   public void setDesiredDirection(  int d )
           {
           direction_ = d;
           }
          
           /**
           * Sets the number of lives for this pacman
           * @param i the number of lives left of pacman you want
           */
     250   public void setLivesLeft(  int i )
           {
           myLivesLeft_ = i;
           }
          
           /**
           * @param n Goes to this node if it is not null
           **/
     258   private void goToNode(  GridNode n )
           {
           if (  n == null ) return;
           myNode_ = n;
           newPixelX_ = myNode_.pixelCenterX(   );
           newPixelY_ = myNode_.pixelCenterY(   );
           }
          
     266   public boolean isInvincible(   )
           {
           if(  invincible_ == true )
           {
           return true;
           }
           else
           {
           return false;
           }
           }
          
           /**
           * Resets Pacman to his original position but keeps the number of pellets eaten
           */
     281   public void restart(   )
           {
           myNode_ = startNode_;
          
           pixelX_ = startNode_.pixelCenterX(   );
           pixelY_ = startNode_.pixelCenterY(   );
           newPixelX_ = startNode_.pixelCenterX(   );
           newPixelY_ = startNode_.pixelCenterY(   );
           invincible_ = false;
          
           direction_ = NONE;
           animDirection_ = RIGHT;
           //currentDirection_ = direction_;
          
           pelletsEaten_ = pelletsEaten_;
          
           // mouthAngle starts Pacman facing right
           mouthAngleDirection_ = 20;
           // 40 degree arc mouth opening
           mouthAngle_ = 320;
           mouthAngleChange_ = +10;
          
           // We only restart when pacman dies,   so...
           myLivesLeft_--;
           }
          
           /**
           * Called to advance the logic of the game one frame.
           **/
     310   public void advanceFrame(   )
           {
           // if we are in an animation:
           if (  (  pixelX_ != newPixelX_ ) || (  pixelY_ != newPixelY_ ) )
           {
           // move closer to the destination:
           if (  pixelX_ < newPixelX_ ) pixelX_++;
           if (  pixelX_ > newPixelX_  ) pixelX_--;
           if (  pixelY_ < newPixelY_ ) pixelY_++;
           if (  pixelY_ > newPixelY_  ) pixelY_--;
           }
           else
           {
           // The else and if else statement directly after this comment
           // were modified over the course of 2 weeks by Trevor Donarski
           //
           // Basically what I did was implement the scoring strategy and
           // the ability for pacman to become invincible once he ate a
           // power pellet (  known as BIG_PELLET ). I call PacmanTimer which
           // is a class that implements the timer function found in
           // java.util.Timer
          
          
           if (  myNode_.getPellet(   ) == GridNode.SMALL_PELLET )
           {
           myNode_.setPellet(  GridNode.NO_PELLET );
           pelletsEaten_++;
           score_++;
           }
          
           // eat any pellets:
           else if (  myNode_.getPellet(   ) == GridNode.BIG_PELLET )
           {
           myNode_.setPellet(  GridNode.NO_PELLET );
           pelletsEaten_+=2;
           score_+=2;
           invincibleTimer = new PacmanTimer(   );
           }
          
           // can we move in the direction requested?
           // Modified 4/3/03 - PDF
           // - Added support for animDirection_
           if(  direction_ == LEFT )
           {
           goToNode(  myNode_.getLeft(   ) );
           animDirection_ = LEFT;
           }
           if(  direction_ == RIGHT )
           {
           goToNode(  myNode_.getRight(   ) );
           animDirection_ = RIGHT;
           }
           if(  direction_ == DOWN )
           {
           goToNode(  myNode_.getDown(   ) );
           animDirection_ = DOWN;
           }
           if(  direction_ == UP )
           {
           goToNode(  myNode_.getUp(   ) );
           animDirection_ = UP;
           }
           }
           }
          
           /**
           * Paints the PacmanActor
           * @param g Graphics object where drawing should take place.
           **/
     379   public void paint(  Graphics g )
           {
           if (  mouthAngle_ <= 300 ) mouthAngleChange_ = +10;
           if (  mouthAngle_ >= 360 ) mouthAngleChange_ = -10;
           mouthAngle_ += mouthAngleChange_;
          
           //Added by Benson Fung - make mouth move correctly
           //Added a variable speed optimization
           //if (  direction_ != currentDirection_ )
           //Modified 4/3/03 - PDF
           // - Now switches on animDirection_ instead of direction_
           switch (  animDirection_ )
           {
           case RIGHT: mouthAngleDirection_ = 30; break; // 0 degrees + 20
           case LEFT: mouthAngleDirection_ = 210; break; // 180 degrees + 20
           case UP: mouthAngleDirection_ = 120; break; // 90 degrees + 20
           case DOWN: mouthAngleDirection_ = 300; break; // 270 degrees + 20
           default: break;
           }
           // both sides of his mouth move,   so this must account for change also
           mouthAngleDirection_ -= mouthAngleChange_;
          
           g.setColor(  0,  0,  0 );
          
           //fillArc(  x,  y,  sizeX,   sizeY,   startAngle,   arcAngle
           //startAngle should determine which side the mouth faces
           //arcAngle should be between 360 - 60 to 360 - 20
           g.fillArc(  pixelX_-4,  
           pixelY_-4,  
           8,  8,  
           mouthAngleDirection_,  
           mouthAngle_ );
           }
          
          /**
           * Simple timer that uses java.util.Timer to schedule a task
           * to execute for 6 seconds
           **/
          
     418  public class PacmanTimer
          {
          
     421   Timer timer;
          
           /**
           * Constructor for PacmanTimer.
           * Creates a new Timer and schedules a task
           * to run in 6000 milliseconds = 6 sec
           **/
     428   public PacmanTimer(   )
           {
           invincible_ = true;
           timer = new Timer (   );
           timer.schedule(  new PacmanTask(   ),   6000 );
           }
          
           /**
           * This is PacmanTask which simply outputs to the screen
           * when the time is up and turns inviciblity off
           **/
          
     440   class PacmanTask extends TimerTask
           {
     442   public void run(   )
           {
           System.out.println(  "Time's up!" );
           //Terminate the timer thread
           timer.cancel(   );
           invincible_ = false;
           }
           }
          
          }
          
          }

SplashScreen.java

       1  import javax.microedition.midlet.*;
          import javax.microedition.lcdui.*;
          import javax.microedition.io.*;
          import java.util.Random;
          
       6  public class SplashScreen extends Canvas implements CommandListener
          {
       8   private final pacman midlet;
       9   private final Command exitCommand;
           private int x;
           private int y = 40;
           private int pacDirection = 1;
           private int mouthAngle = 320;
           private int mouthAngleChange = 10;
           private int mouthAngleDirection = 20;
      16   private SplashTrigger splashTrigger;
      17   private Random generator = new Random(   );
          
      19   public SplashScreen(  pacman midlet )
           {
           this.midlet = midlet;
          
           exitCommand = new Command(  "Next",   Command.EXIT,   1 );
           addCommand(  exitCommand );
           setCommandListener(  this );
           splashTrigger = new SplashTrigger(  this,   20 );
           splashTrigger.start(   );
           }
          
      30   public void paint(  Graphics g )
           {
           g.setColor(  255,  255,  255 );
           g.fillRect(  0,  0,  120,  120 );
           g.setColor(  0,  0,  0 );
           g.setFont(  Font.getFont(  Font.FACE_PROPORTIONAL,  Font.STYLE_BOLD,  Font.SIZE_LARGE ) );
           g.drawString(  "PacMan",  25,  5,   (  Graphics.TOP | Graphics.LEFT ) );
           animateScene(  g );
           }
          
      40   public void animateScene(  Graphics g )
           {
           if (  mouthAngle <= 300 ) mouthAngleChange = +10;
           if (  mouthAngle >= 360 ) mouthAngleChange = -10;
           mouthAngle += mouthAngleChange;
           mouthAngleDirection -= mouthAngleChange;
          
           g.setColor(  0,  0,  0 );
           g.fillArc(  x,  
           y,  
           8,  8,  
           mouthAngleDirection,  
           mouthAngle );
          
           g.drawArc(  x-30,  
           y,  
           8,  8,  
           0,  
           360 );
          
           g.drawArc(  x-50,  
           y,  
           8,  8,  
           0,  
           360 );
          
           g.drawArc(  x-70,  
           y,  
           8,  8,  
           0,  
           360 );
           }
          
      73   public void advanceFrame(   )
           {
           x += pacDirection * 1;
           if (  x == 180 ) {
           pacDirection = -1;
           mouthAngleDirection = 210;
           y = Math.abs(  generator.nextInt(   ) % 40 ) + 25;
           }
           if (  x == -30 ) {
           pacDirection = 1;
           mouthAngleDirection = 20;
           y = Math.abs(  generator.nextInt(   ) % 40 ) + 25;
           }
           repaint(   );
           }
          
      89   public void commandAction(  Command c,   Displayable d )
           {
           if (  c == exitCommand )
           {
           splashTrigger.stopTrigger(   );
           midlet.splashScreenDone(   );
           }
           }

SplashTrigger.java

       1  import javax.microedition.lcdui.*;
          import javax.microedition.midlet.*;
          
          
          /**
           * This trigger is responsible for calling advanceFrame(   ) on a SplashScreen
           * object.
           **/
       9  public class SplashTrigger extends Thread
          {
          
           /**
           * The SplashScreen where we call advanceFrame.
           **/
      15   private SplashScreen splashScreen;
          
           /**
           * Time is miliseconds between frames
           **/
           private int frameDelay;
          
           /**
           * Value which is true if the thread is to be stopped.
           **/
           private boolean stopped;
          
           /**
           * Constructor
           * @param g Canvas for wich to trigger frame updates.
           * @param frameDelay time in MS between frame updates.
           **/
      32   public SplashTrigger(  SplashScreen g,   int frameDelay )
           {
           this.splashScreen = g;
           this.frameDelay = frameDelay;
           }
          
           /**
           * Stops the trigger from functioning.
           * (  stops execution of the thread )
           **/
      42   public void stopTrigger(   )
           { stopped = true; }
          
           /**
           * Starts the trigger running.
           * - To be called by the thead start(   ) function call.
           **/
      49   public void run(   )
           {
           stopped=false;
           while (  !stopped )
           {
           splashScreen.advanceFrame(   );
           try {
           sleep(  frameDelay );
           } catch (  InterruptedException ie ) {}
           }
           }
          

pacman.java

       1  /**
           * PacMan for J2ME Devices
           * CS 327 - Design Project,   Fall 2002
           * University of Illinois,   Urbana-Champaign
           *
           * file: pacman.java
           * contact: Braden Kowitz
           * date: 11/24/02
           **/
          
          //----------------------------------------------------------------------------//
          
          import javax.microedition.midlet.*;
          import javax.microedition.lcdui.*;
          
          /**
           * This is the base class for the midlet.
           * It starts up and shuts down the game.
           **/
      20  public class pacman extends MIDlet
          {
          
           /**
           * A canvas draws to the screen.
           * The game canvas contains all of main
           * functionality of the gameplay.
           **/
      28   private GameCanvas gameCanvas;
      29   private SplashScreen splashScreen;
      30   private MenuScreen menuScreen;
          
           public int gameOver;
          
          
           /**
           * Constructor for this MIDlet.
           * This function get's the current display,  
           * and creates a GameCanvas with the display.
           **/
      40   public pacman(   )
           {
           }
          
           /**
           * When the OS tells this midlet to start,  
           * we simply show the GameCanvas.
           **/
      48   public void startApp(   )
           {
           gameOver = 1;
           Displayable current = Display.getDisplay(  this ).getCurrent(   );
           if(  current == null )
           {
           // first time we've been called
           splashScreen = new SplashScreen(  this );
           Display.getDisplay(  this ).setCurrent(  splashScreen );
           }
           else
           {
           Display.getDisplay(  this ).setCurrent(  current );
           }
           }
          
           /**
           * Handles a request from the OS to pause the game.
           * This is not currently implemented.
           **/
      68   public void pauseApp(   )
           {
           }
          
           /**
           * Handles a restart of the game
           */
      75   public void restartApp(   ) throws MIDletStateChangeException
           {
           gameOver = 0;
           gameCanvas = new GameCanvas(  this );
           Display.getDisplay(  this ).setCurrent(  gameCanvas );
           }
          
      82   public void continueGame(   )
           {
           gameCanvas.unPause(   );
           Display.getDisplay(  this ).setCurrent(  gameCanvas );
           }
          
           /**
           * Handles a request from the OS to end the game.
           * Calls to destroy FrameTrigger thread accessable
           * in GameCanvas
           **/
      93   public void destroyApp(  boolean unconditional )
           {
           }
          
      97   public void splashScreenDone(   )
           {
           menuScreen = new MenuScreen(  this );
           Display.getDisplay(  this ).setCurrent(  menuScreen );
           }
          
     103   public void menuScreen(   )
           {
           menuScreen = new MenuScreen(  this );
           Display.getDisplay(  this ).setCurrent(  menuScreen );
           }
          
     109   public void quit(   )
           {
           destroyApp(  false );
           notifyDestroyed(   );
           }