Spaces:
Running
Running
| // Game constants | |
| const CELL_SIZE = 20; | |
| const PACMAN_SPEED = 2; | |
| const GHOST_SPEED = 1.5; | |
| const POWER_PELLET_DURATION = 500; // frames | |
| // Game state | |
| let score = 0; | |
| let lives = 3; | |
| let gameRunning = false; | |
| let powerMode = false; | |
| let powerModeTimer = 0; | |
| // Canvas setup | |
| const canvas = document.getElementById('gameCanvas'); | |
| const ctx = canvas.getContext('2d'); | |
| // DOM elements | |
| const scoreElement = document.getElementById('score'); | |
| const livesElement = document.getElementById('lives'); | |
| const startButton = document.getElementById('startButton'); | |
| // Game objects | |
| let pacman = { | |
| x: 14 * CELL_SIZE, | |
| y: 23 * CELL_SIZE, | |
| radius: CELL_SIZE / 2 - 2, | |
| direction: 'right', | |
| nextDirection: 'right', | |
| mouthOpen: 0, | |
| mouthChange: 0.1 | |
| }; | |
| let ghosts = [ | |
| { x: 13 * CELL_SIZE, y: 11 * CELL_SIZE, color: '#FF0000', direction: 'left', speed: GHOST_SPEED, frightened: false }, // Blinky | |
| { x: 14 * CELL_SIZE, y: 14 * CELL_SIZE, color: '#FFB8FF', direction: 'up', speed: GHOST_SPEED, frightened: false }, // Pinky | |
| { x: 12 * CELL_SIZE, y: 14 * CELL_SIZE, color: '#00FFFF', direction: 'down', speed: GHOST_SPEED, frightened: false }, // Inky | |
| { x: 15 * CELL_SIZE, y: 14 * CELL_SIZE, color: '#FFB852', direction: 'right', speed: GHOST_SPEED, frightened: false } // Clyde | |
| ]; | |
| // Maze layout (1 = wall, 0 = dot, 2 = empty, 3 = power pellet) | |
| const maze = [ | |
| [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], | |
| [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], | |
| [1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1], | |
| [1, 3, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 3, 1], | |
| [1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1 |