A multithreaded Pacman clone built with Java Swing. The game features a procedurally generated maze rendered via a custom JTable model, four independently threaded ghosts, keyboard-driven player movement, a persistent high score system, and a fully interactive GUI with no CLI interaction required.
The player controls Pacman on a dynamically generated board (configurable from 10×10 to 100×100 cells). Pacman collects dots while avoiding four ghosts that move independently on their own threads. The game tracks score, lives, and provides a persistent high score ranking saved to file.
- Language: Java (standard library only)
- GUI: Java Swing (JFrame, JTable, JList, JPanel, JOptionPane)
- Table model: Custom
AbstractTableModelfor the game board - List model: Custom
AbstractListModelfor the high score list - Rendering: Custom
DefaultTableCellRendererwith sprite-based cell rendering - Concurrency:
java.lang.Thread,synchronizedblocks - Persistence: File I/O with
Scanner/PrintWriterfor high score storage
src/
├── Main.java # Entry point
├── UI/
│ ├── Menu.java # Main menu window (New Game, High Score, Exit)
│ └── Game.java # Game window, thread management, input handling
├── Pacman/
│ └── Pacman.java # Player entity (Runnable), movement logic
├── Ghost/
│ └── Ghost.java # Ghost entity (Runnable), random AI movement
├── Board/
│ ├── GameBoard.java # AbstractTableModel, procedural maze generation
│ └── GameBoardColorRenderer.java # Cell renderer with sprite support
├── Ranking/
│ ├── HighScoreModel.java # AbstractListModel, file-based persistence
│ └── Player.java # Player name + score data object
├── Exceptions/
│ └── InvalidBoardSizeException.java # Thrown for board sizes outside 10-100 range
└── Images/ # Sprite assets (Pacman, ghosts, dots)
Prerequisites: JDK 11 or later.
# Compile
find src -name "*.java" | xargs javac -d out
# Run
java -cp out MainImportant: The game loads sprite images from src/Images/ using relative paths. Run the application from the project root directory to ensure images load correctly.
- Launch the application — the main menu appears.
- Click NEW GAME and enter board dimensions (10–100 rows and columns).
- Use arrow keys to move Pacman.
- Collect dots (score +1 per dot) while avoiding ghosts.
- Pacman starts with 3 lives. Contact with a ghost costs one life.
- Press Ctrl+Shift+Q at any time to quit and return to menu.
- After game over, enter your name for the high score ranking.
- Click HIGH SCORE from the menu to view saved rankings.
- Board as JTable: The game board is backed by
AbstractTableModel. Each cell holds an integer code (0 = empty, 1 = wall, 3 = Pacman, 4–7 = ghosts, 8 = dot). A customDefaultTableCellRenderermaps these codes to colors or sprite images. - One thread per entity: Pacman and each ghost run on independent threads. A separate verification thread checks for collisions and manages lives.
- Ghost AI: Ghosts move randomly, re-randomizing direction at intersections (when more than 2 paths are available). They preserve the previous cell value to restore dots after passing over them.
- Maze generation: The board is procedurally generated using a symmetric pattern based on row/column indices, producing a maze with corridors and walls.
- Ghost movement is purely random with no pathfinding toward the player.
- Image paths are hardcoded as relative paths from the working directory.
- No power-ups or ghost vulnerability mode is implemented.
Additional documentation is available in the docs/ directory:
- Architecture — threading model, MVC structure, rendering pipeline
- Setup and Run — compilation and execution
- Codebase Overview — package-by-package breakdown
- Usage — gameplay guide and controls