Okay, here is a complete Pac-Man game implemented in a single HTML file using HTML, CSS, and JavaScript.
This single HTML file contains the structure (HTML), styling (CSS within <style>), and all the game logic (JavaScript within <script>). Open this index.html file in your browser to play the game. Use the arrow keys to control Pac-Man.
Okay, it seems like there might be an issue in the drawing logic or an early JavaScript error stopping the execution after drawing just one part of the map (likely the first wall tile).
Let's refine the code, particularly focusing on the drawing functions and ensuring the game loop runs correctly. I'll also adjust how collision detection and movement permissions are handled to be more robust.
Key Changes:
pacman.x, pacman.y, ghost.x, ghost.y now represent the center.canMove Refinement: The canMove function now takes the entity as an argument and checks collision points around the entity's perimeter based on its radius and potential next position. It handles walls, ghost gate logic, and tunnel boundaries more explicitly.isAlignedToGrid helper function to check if an entity is close enough to the center of a tile, which is crucial for making turns at intersections. Turns are now only allowed when aligned. Entities also snap to the grid center when turning or stopping at a wall.IN_HOUSE, EXITING) and logic for ghosts entering, waiting (with bobbing), exiting, and returning when eaten. Added simple exit delays.chooseBestDirection and chooseRandomDirection now use the refined canMove and grid alignment checks. Ghosts prioritize directions based on standard Pac-Man rules (Up > Left > Right > Down).gameStarted flag and a "Ready?" timer. The game loop now handles the initial delay and stops correctly on permanent game over or win. handleDeath temporarily sets gameOver to pause updates during the death sequence.map array (though the original seemed okay, adjusted to common layouts). Ensured canvas height matches map rows.event.code for better keyboard layout compatibility. Allowed immediate 180-degree turns.This revised version addresses potential issues with collision, movement logic, state management, and drawing that might have caused the previous version to fail or render incorrectly. Try running this updated index.html._
Okay, if the drawing is correct but Pac-Man isn't moving, the issue likely lies in the input handling, the movement update logic (updatePacman), or the collision detection (canMove) preventing any movement from starting.
Let's add some console.log statements to help diagnose where the process is breaking down and refine the movement logic slightly.
gameStarted is true, gameOver is false).pacman.dx or pacman.dy.canMove is preventing the initial move.Here's the updated code with logging and minor adjustments:
Key Changes & Debugging Focus:
handleInput: Added logs to confirm key presses are detected and requestedDirection is set. Also added logic to potentially set the initial direction during the "Ready?" phase if the move is valid, allowing Pac-Man to start moving immediately when gameStarted becomes true.updatePacman:
console.log) to trace the flow: checking requestedDirection, alignment (isAlignedToGrid), and collision (canMove) during turns and forward movement. Check your browser's developer console (usually F12) for these messages.canMove for the turn. It also has a condition to start movement if currently stopped.pacman.dx or pacman.dy is non-zero and canMove allows it.isAlignedToGrid: Added logging and adjusted the tolerance slightly based on speed. This function is critical for allowing turns only at the correct spots.canMove: Added logging to pinpoint potential collision issues. Made sure tunnel logic correctly handles coordinates going out of bounds.init: Corrected Pac-Man's starting X coordinate to be properly centered (TILE_SIZE * 10.5). Reset readyTimer in init.gameStarted becomes true and when the loop stops. Capped deltaTime to prevent extreme jumps if the tab loses focus.gameOver correctly pauses updates during the death sequence and resumes if lives remain. gameWon also stops updates. Input is ignored if gameOver or gameWon.To Use:
index.html file in your browser.Key pressed..., Requested Direction Set...).updatePacman each frame (alignment, turn attempts, movement attempts, canMove results).gameStarted becomes true.Look for patterns: Is requestedDirection being set but never applied? Is isAlignedToGrid always false? Is canMove always returning false when you try to move? The console logs should guide you to the exact point of failure._
Okay, the logs show the game initializes, starts, then Pac-Man immediately dies, resets, and dies again. This strongly suggests an instant collision is happening right at the start of the level or immediately after Pac-Man respawns.
The most likely causes are:
10.5 * TILE_SIZE, 16.5 * TILE_SIZE) is somehow causing an immediate collision check failure with a ghost's initial/reset position (especially Blinky, who starts outside the house at 10.5 * TILE_SIZE, 8.5 * TILE_SIZE).checkGhostCollisions function's distance calculation or threshold is triggering incorrectly at the start.CHASE instead of going back to IN_HOUSE or SCATTER appropriately) and instantly hits the newly spawned Pac-Man.Let's add more specific logging inside checkGhostCollisions to see exactly which ghost is causing the collision and what their positions/states are. We'll also log the positions during the reset.
Changes Made:
checkGhostCollisions: Added a console.log that prints the positions, states, distance, and threshold only when Pac-Man and a ghost are potentially close (within one tile + threshold). This helps identify the culprit without flooding the console. Also added a specific log when a collision is detected. Made the collision threshold slightly more lenient (- 2 instead of - 4).resetPositionsAfterDeath: Added logs to confirm Pac-Man's reset position and that ghosts are being recreated. Recreating ghosts (createGhosts()) is generally the safest way to ensure they are in the correct initial state after a death.handleDeath: Slightly shortened the delay. Crucially, ensured gameOver is set to true immediately to stop further updates during the pause, and only set back to false after positions are reset and the new readyTimer starts.createGhosts: Added logging to show the state and position of each ghost upon creation/reset. Increased the staggering of exit delays.init: Ensured pacman object is defined before createGhosts is called. Added logging for Pac-Man's initial position.update function: game must be started, not currently in the death pause (!gameOver), and not won.Next Steps:
Collision Check: logs. Which ghost (Ghost id) is close to Pac-Man? What are their states and positions? Is the distance less than the threshold immediately?!!! Collision detected !!! log. This confirms which ghost triggered handleDeath.This detailed logging should pinpoint exactly why the instant death is occurring._
Okay, if the ghosts aren't leaving the cage, the problem is likely within the state management for IN_HOUSE and EXITING states in the updateGhosts function, or potentially how canMove handles the ghost house tiles (4 and 5) for ghosts trying to leave.
Let's focus on debugging that specific logic:
console.log statements within the IN_HOUSE and EXITING state blocks in updateGhosts to track their progress.canMove: Double-check the conditions in canMove related to ghosts, the gate (tile 4), and the house interior (tile 5). Ensure exiting ghosts can pass through the gate.ghostHouseCenter and ghostExitPos are correct relative to the map.Here's the code with added logging specifically for ghost exiting:
Changes Made:
canMove: Explicitly added continue statements for tile 5 (house interior) and tile 4 (gate) when the ghost state is EXITING or EATEN. This ensures they are allowed to be on these tiles in those specific states. Added a check to block non-exiting/eaten ghosts from entering the gate (tile 4).updateGhosts:
IN_HOUSE state to track the exitDelayTimer.EXITING.EXITING state to track the ghost's Y position relative to the target ghostExitPos.y.console.error) if canMove returns false during an EXITING movement attempt, as this indicates a problem.console.warn) if any ghost movement gets blocked.How to Debug:
Ghost X ...:
Waiting in house...? Does the timer decrease?Reached center X, changing state to EXITING...?Exiting. y=..., targetY=...? Does the y value decrease towards the targetY?CANNOT MOVE while EXITING! errors? If so, this points directly to the canMove function or the coordinates being wrong.Exited house! ...?This should clearly show at which step the exiting process is failing for each ghost (Pinky, Inky, Clyde).*_