| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Pac-Man Game</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <style> |
| @keyframes pacman-mouth { |
| 0% { clip-path: polygon(50% 50%, 100% 0%, 100% 100%); } |
| 50% { clip-path: polygon(50% 50%, 100% 40%, 100% 60%); } |
| 100% { clip-path: polygon(50% 50%, 100% 0%, 100% 100%); } |
| } |
| |
| @keyframes ghost-movement { |
| 0% { transform: translateY(0); } |
| 50% { transform: translateY(-5px); } |
| 100% { transform: translateY(0); } |
| } |
| |
| @keyframes pulse { |
| 0% { transform: scale(1); } |
| 50% { transform: scale(1.2); } |
| 100% { transform: scale(1); } |
| } |
| |
| @keyframes blink { |
| 0%, 100% { opacity: 1; } |
| 50% { opacity: 0.5; } |
| } |
| |
| .pacman { |
| animation: pacman-mouth 0.5s infinite; |
| } |
| |
| .ghost { |
| animation: ghost-movement 1s infinite; |
| } |
| |
| .ghost::before { |
| content: ''; |
| position: absolute; |
| width: 20px; |
| height: 10px; |
| background: white; |
| border-radius: 100px 100px 0 0; |
| top: -10px; |
| left: 10px; |
| } |
| |
| .ghost::after { |
| content: ''; |
| position: absolute; |
| width: 4px; |
| height: 4px; |
| background: black; |
| border-radius: 50%; |
| top: -5px; |
| left: 15px; |
| box-shadow: 10px 0 black; |
| } |
| |
| .ghost-eye { |
| width: 6px; |
| height: 6px; |
| background: white; |
| border-radius: 50%; |
| position: absolute; |
| top: -3px; |
| left: 13px; |
| } |
| |
| .ghost-pupil { |
| width: 2px; |
| height: 2px; |
| background: black; |
| border-radius: 50%; |
| position: absolute; |
| top: 1px; |
| left: 1px; |
| } |
| |
| .wall { |
| background-color: #2563eb; |
| box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.5); |
| } |
| |
| .dot { |
| width: 6px; |
| height: 6px; |
| background-color: #fbbf24; |
| border-radius: 50%; |
| box-shadow: 0 0 5px #fbbf24; |
| } |
| |
| .power-pellet { |
| width: 12px; |
| height: 12px; |
| background-color: #fbbf24; |
| border-radius: 50%; |
| box-shadow: 0 0 10px #fbbf24; |
| animation: pulse 1s infinite; |
| } |
| |
| .fruit { |
| width: 16px; |
| height: 16px; |
| background-color: #dc2626; |
| border-radius: 8px; |
| box-shadow: 0 0 8px #dc2626; |
| } |
| |
| #game-board { |
| position: relative; |
| width: 560px; |
| height: 620px; |
| border: 2px solid #1e40af; |
| background-color: #1e1b4b; |
| } |
| |
| .cell { |
| width: 20px; |
| height: 20px; |
| position: absolute; |
| } |
| |
| #score-display { |
| font-family: 'Courier New', monospace; |
| letter-spacing: 2px; |
| } |
| |
| #game-over, #start-screen { |
| background-color: rgba(0, 0, 0, 0.8); |
| z-index: 100; |
| } |
| |
| .press-enter { |
| animation: blink 1.5s infinite; |
| } |
| |
| .title-shadow { |
| text-shadow: 0 0 10px #fbbf24, 0 0 20px #fbbf24; |
| } |
| |
| #start-screen { |
| cursor: pointer; |
| } |
| </style> |
| </head> |
| <body class="bg-gray-900 min-h-screen flex flex-col items-center justify-center p-4"> |
| <div id="start-screen" class="absolute w-full h-full flex flex-col items-center justify-center text-white"> |
| <h1 class="text-6xl font-bold text-yellow-400 mb-8 title-shadow">PAC-MAN</h1> |
| <div class="text-2xl mb-8"> |
| <div class="flex justify-center items-center mb-4"> |
| <div class="pacman w-10 h-10 bg-yellow-400 rounded-full mr-4"></div> |
| <div class="ghost w-10 h-10 bg-red-500 rounded-t-full relative"></div> |
| </div> |
| <p class="press-enter text-3xl mt-8">PRESS ENTER TO START</p> |
| <p class="text-xl mt-4">(or click anywhere)</p> |
| </div> |
| </div> |
|
|
| <div class="text-center mb-4 hidden" id="game-header"> |
| <h1 class="text-4xl font-bold text-yellow-400 mb-2">PAC-MAN</h1> |
| <div id="score-display" class="text-2xl font-mono text-white"> |
| SCORE: <span id="score">0</span> |
| </div> |
| </div> |
|
|
| <div id="game-board" class="relative hidden"></div> |
|
|
| <div class="mt-4 text-white hidden" id="game-controls"> |
| <p class="mb-2">Use arrow keys to move Pac-Man</p> |
| <button id="restart-btn" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded hidden"> |
| Play Again |
| </button> |
| </div> |
|
|
| <div id="game-over" class="absolute hidden flex-col items-center justify-center text-white"> |
| <h2 class="text-4xl font-bold text-red-500 mb-4">GAME OVER</h2> |
| <p class="text-2xl mb-4">Final Score: <span id="final-score">0</span></p> |
| <button id="game-over-restart" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"> |
| Play Again |
| </button> |
| </div> |
|
|
| <script> |
| document.addEventListener('DOMContentLoaded', () => { |
| |
| const CELL_SIZE = 20; |
| const ROWS = 31; |
| const COLS = 28; |
| const BOARD_WIDTH = COLS * CELL_SIZE; |
| const BOARD_HEIGHT = ROWS * CELL_SIZE; |
| const FRUIT_DURATION = 10000; |
| |
| |
| let score = 0; |
| let lives = 3; |
| let pacman = { x: 14, y: 23, direction: 'right', nextDirection: 'right' }; |
| let ghosts = []; |
| let dots = []; |
| let powerPellets = []; |
| let walls = []; |
| let gameRunning = false; |
| let scaredGhosts = false; |
| let scaredTimer = null; |
| let pacmanBoost = false; |
| let pacmanBoostTimer = null; |
| let fruit = null; |
| let fruitTimer = null; |
| |
| |
| const layout = [ |
| '1111111111111111111111111111', |
| '1............o............1', |
| '1.1111.11111.111.11111.1111', |
| '1.1111.11111.111.11111.1111', |
| '1.1111.11111.111.11111.1111', |
| '1..........................1', |
| '1.1111.111.111111.111.1111', |
| '1.1111.111.111111.111.1111', |
| '1......111....11....111....1', |
| '111111.111111.111111.111111', |
| '111111.111111.111111.111111', |
| '111111.111 111.1111', |
| '111111.111 111111 111.1111', |
| '111111.111 1 1 111.1111', |
| '1............1 1......1', |
| '1.1111.11111 111111 111.11', |
| '1.1111.11111 111.11', |
| '1.1111.11111 111111 111.111', |
| '1......11111 1 1 111....1', |
| '111111.11111 1 1 111.1111', |
| '111111.11111 111111 111.1111', |
| '111111.11111 111.1111', |
| '1............111111......1', |
| '1.1111.11111.111.11111.1111', |
| '1.1111.11111.111.11111.1111', |
| '1...o.......111....o.....1', |
| '111.111.111.111111.111.1111', |
| '111.111.111.111111.111.1111', |
| '1......111....11....111....1', |
| '1.11111111111.111.1111111.1', |
| '1..........................1', |
| '1111111111111111111111111111' |
| ]; |
| |
| |
| function initGame() { |
| score = 0; |
| lives = 3; |
| document.getElementById('score').textContent = score; |
| document.getElementById('game-over').classList.add('hidden'); |
| document.getElementById('restart-btn').classList.add('hidden'); |
| |
| |
| document.getElementById('game-header').classList.remove('hidden'); |
| document.getElementById('game-board').classList.remove('hidden'); |
| document.getElementById('game-controls').classList.remove('hidden'); |
| |
| |
| document.getElementById('game-board').innerHTML = ''; |
| dots = []; |
| powerPellets = []; |
| walls = []; |
| ghosts = []; |
| fruit = null; |
| if (fruitTimer) clearTimeout(fruitTimer); |
| |
| |
| for (let y = 0; y < ROWS; y++) { |
| for (let x = 0; x < COLS; x++) { |
| const cell = layout[y][x]; |
| const cellElement = document.createElement('div'); |
| cellElement.className = 'cell'; |
| cellElement.style.left = `${x * CELL_SIZE}px`; |
| cellElement.style.top = `${y * CELL_SIZE}px`; |
| |
| if (cell === '1') { |
| |
| cellElement.classList.add('wall'); |
| walls.push({ x, y }); |
| } else if (cell === '.') { |
| |
| const dot = document.createElement('div'); |
| dot.className = 'dot'; |
| dot.style.left = `${x * CELL_SIZE + 7}px`; |
| dot.style.top = `${y * CELL_SIZE + 7}px`; |
| document.getElementById('game-board').appendChild(dot); |
| dots.push({ x, y, element: dot }); |
| } else if (cell === 'o') { |
| |
| const pellet = document.createElement('div'); |
| pellet.className = 'power-pellet'; |
| pellet.style.left = `${x * CELL_SIZE + 4}px`; |
| pellet.style.top = `${y * CELL_SIZE + 4}px`; |
| document.getElementById('game-board').appendChild(pellet); |
| powerPellets.push({ x, y, element: pellet }); |
| } |
| } |
| } |
| |
| |
| const pacmanElement = document.createElement('div'); |
| pacmanElement.id = 'pacman'; |
| pacmanElement.className = 'pacman absolute w-5 h-5 bg-yellow-400 rounded-full'; |
| pacmanElement.style.left = `${pacman.x * CELL_SIZE}px`; |
| pacmanElement.style.top = `${pacman.y * CELL_SIZE}px`; |
| document.getElementById('game-board').appendChild(pacmanElement); |
| |
| |
| createGhost('blinky', 13, 11, 'red'); |
| createGhost('pinky', 14, 11, 'pink'); |
| createGhost('inky', 13, 14, 'cyan'); |
| createGhost('clyde', 14, 14, 'orange'); |
| |
| gameRunning = true; |
| requestAnimationFrame(gameLoop); |
| startFruitAppearance(); |
| } |
| |
| function createGhost(id, x, y, color) { |
| const ghost = { |
| id, |
| x, |
| y, |
| direction: 'up', |
| speed: 0.8, |
| isScared: false, |
| isEaten: false |
| }; |
| |
| const ghostElement = document.createElement('div'); |
| ghostElement.id = id; |
| ghostElement.className = `ghost absolute w-5 h-5 bg-${color}-500 rounded-t-full`; |
| ghostElement.style.left = `${x * CELL_SIZE}px`; |
| ghostElement.style.top = `${y * CELL_SIZE}px`; |
| |
| |
| const leftEye = document.createElement('div'); |
| leftEye.className = 'ghost-eye'; |
| leftEye.style.left = '8px'; |
| |
| const rightEye = document.createElement('div'); |
| rightEye.className = 'ghost-eye'; |
| rightEye.style.left = '18px'; |
| |
| const leftPupil = document.createElement('div'); |
| leftPupil.className = 'ghost-pupil'; |
| |
| const rightPupil = document.createElement('div'); |
| rightPupil.className = 'ghost-pupil'; |
| |
| leftEye.appendChild(leftPupil); |
| rightEye.appendChild(rightPupil); |
| ghostElement.appendChild(leftEye); |
| ghostElement.appendChild(rightEye); |
| |
| document.getElementById('game-board').appendChild(ghostElement); |
| ghost.element = ghostElement; |
| ghosts.push(ghost); |
| |
| return ghost; |
| } |
| |
| |
| function gameLoop(timestamp) { |
| if (!gameRunning) return; |
| |
| movePacman(); |
| moveGhosts(); |
| checkCollisions(); |
| updateDisplay(); |
| |
| if (dots.length === 0 && powerPellets.length === 0) { |
| |
| gameRunning = false; |
| setTimeout(() => { |
| alert('You Won! Final Score: ' + score); |
| initGame(); |
| }, 500); |
| return; |
| } |
| |
| requestAnimationFrame(gameLoop); |
| } |
| |
| |
| function movePacman() { |
| const pacmanElement = document.getElementById('pacman'); |
| |
| |
| if (pacman.nextDirection !== pacman.direction) { |
| const nextX = Math.round(pacman.x); |
| const nextY = Math.round(pacman.y); |
| |
| if (canMove(nextX, nextY, pacman.nextDirection)) { |
| pacman.direction = pacman.nextDirection; |
| } |
| } |
| |
| |
| let newX = pacman.x; |
| let newY = pacman.y; |
| |
| switch (pacman.direction) { |
| case 'left': |
| newX -= 0.2; |
| pacmanElement.style.transform = 'rotate(180deg)'; |
| break; |
| case 'right': |
| newX += 0.2; |
| pacmanElement.style.transform = 'rotate(0deg)'; |
| break; |
| case 'up': |
| newY -= 0.2; |
| pacmanElement.style.transform = 'rotate(-90deg)'; |
| break; |
| case 'down': |
| newY += 0.2; |
| pacmanElement.style.transform = 'rotate(90deg)'; |
| break; |
| } |
| |
| |
| if (canMove(Math.floor(newX), Math.floor(newY), pacman.direction)) { |
| pacman.x = newX; |
| pacman.y = newY; |
| |
| |
| if (pacman.x < 0) pacman.x = COLS - 1; |
| if (pacman.x >= COLS) pacman.x = 0; |
| |
| |
| pacmanElement.style.left = `${pacman.x * CELL_SIZE}px`; |
| pacmanElement.style.top = `${pacman.y * CELL_SIZE}px`; |
| } |
| } |
| |
| |
| function moveGhosts() { |
| ghosts.forEach(ghost => { |
| if (ghost.isEaten) { |
| |
| const targetX = 13; |
| const targetY = 11; |
| |
| if (ghost.x < targetX) ghost.direction = 'right'; |
| else if (ghost.x > targetX) ghost.direction = 'left'; |
| else if (ghost.y < targetY) ghost.direction = 'down'; |
| else if (ghost.y > targetY) ghost.direction = 'up'; |
| else { |
| ghost.isEaten = false; |
| ghost.isScared = false; |
| ghost.element.classList.remove('bg-blue-500'); |
| ghost.element.classList.add(`bg-${ghost.id === 'blinky' ? 'red' : ghost.id === 'pinky' ? 'pink' : ghost.id === 'inky' ? 'cyan' : 'orange'}-500`); |
| } |
| } else { |
| |
| const directions = ['up', 'down', 'left', 'right']; |
| const oppositeDir = { |
| 'up': 'down', |
| 'down': 'up', |
| 'left': 'right', |
| 'right': 'left' |
| }; |
| |
| |
| const possibleDirections = directions.filter(dir => dir !== oppositeDir[ghost.direction]); |
| |
| |
| const validDirections = possibleDirections.filter(dir => { |
| const testX = Math.floor(ghost.x); |
| const testY = Math.floor(ghost.y); |
| return canMove(testX, testY, dir); |
| }); |
| |
| if (validDirections.length > 0) { |
| |
| ghost.direction = validDirections[Math.floor(Math.random() * validDirections.length)]; |
| } |
| } |
| |
| |
| let newX = ghost.x; |
| let newY = ghost.y; |
| |
| switch (ghost.direction) { |
| case 'left': |
| newX -= ghost.speed * 0.05; |
| break; |
| case 'right': |
| newX += ghost.speed * 0.05; |
| break; |
| case 'up': |
| newY -= ghost.speed * 0.05; |
| break; |
| case 'down': |
| newY += ghost.speed * 0.05; |
| break; |
| } |
| |
| |
| if (canMove(Math.floor(newX), Math.floor(newY), ghost.direction)) { |
| ghost.x = newX; |
| ghost.y = newY; |
| |
| |
| if (ghost.x < 0) ghost.x = COLS - 1; |
| if (ghost.x >= COLS) ghost.x = 0; |
| |
| |
| ghost.element.style.left = `${ghost.x * CELL_SIZE}px`; |
| ghost.element.style.top = `${ghost.y * CELL_SIZE}px`; |
| } |
| }); |
| } |
| |
| |
| function canMove(x, y, direction) { |
| |
| if (y < 0 || y >= ROWS) return false; |
| |
| |
| const nextX = direction === 'left' ? x - 1 : direction === 'right' ? x + 1 : x; |
| const nextY = direction === 'up' ? y - 1 : direction === 'down' ? y + 1 : y; |
| |
| |
| if (nextX < 0 || nextX >= COLS) { |
| return y === 14 && (nextX < 0 || nextX >= COLS); |
| } |
| |
| if (nextY < 0 || nextY >= ROWS) return false; |
| |
| return layout[nextY][nextX] !== '1'; |
| } |
| |
| |
| function placeFruit() { |
| if (fruit) { |
| document.getElementById('game-board').removeChild(fruit.element); |
| fruit = null; |
| } |
| |
| const emptyCells = []; |
| for (let y = 0; y < ROWS; y++) { |
| for (let x = 0; x < COLS; x++) { |
| if (layout[y][x] === '0') { |
| emptyCells.push({ x, y }); |
| } |
| } |
| } |
| |
| if (emptyCells.length > 0) { |
| const randomIndex = Math.floor(Math.random() * emptyCells.length); |
| const fruitPosition = emptyCells[randomIndex]; |
| |
| const fruitElement = document.createElement('div'); |
| fruitElement.className = 'fruit absolute'; |
| fruitElement.style.left = `${fruitPosition.x * CELL_SIZE + 2}px`; |
| fruitElement.style.top = `${fruitPosition.y * CELL_SIZE + 2}px`; |
| document.getElementById('game-board').appendChild(fruitElement); |
| |
| fruit = { x: fruitPosition.x, y: fruitPosition.y, element: fruitElement }; |
| |
| |
| fruitTimer = setTimeout(() => { |
| if (fruit) { |
| document.getElementById('game-board').removeChild(fruit.element); |
| fruit = null; |
| } |
| }, FRUIT_DURATION); |
| } |
| } |
| |
| |
| function startFruitAppearance() { |
| |
| const randomDelay = Math.random() * 10000 + 5000; |
| setTimeout(placeFruit, randomDelay); |
| } |
| |
| |
| function checkCollisions() { |
| const pacmanCellX = Math.round(pacman.x); |
| const pacmanCellY = Math.round(pacman.y); |
| |
| |
| for (let i = dots.length - 1; i >= 0; i--) { |
| const dot = dots[i]; |
| if (dot.x === pacmanCellX && dot.y === pacmanCellY) { |
| |
| document.getElementById('game-board').removeChild(dot.element); |
| dots.splice(i, 1); |
| score += 10; |
| document.getElementById('score').textContent = score; |
| } |
| } |
| |
| |
| for (let i = powerPellets.length - 1; i >= 0; i--) { |
| const pellet = powerPellets[i]; |
| if (pellet.x === pacmanCellX && pellet.y === pacmanCellY) { |
| |
| document.getElementById('game-board').removeChild(pellet.element); |
| powerPellets.splice(i, 1); |
| score += 50; |
| document.getElementById('score').textContent = score; |
| |
| |
| scaredGhosts = true; |
| ghosts.forEach(ghost => { |
| if (!ghost.isEaten) { |
| ghost.isScared = true; |
| ghost.element.classList.remove(`bg-${ghost.id === 'blinky' ? 'red' : ghost.id === 'pinky' ? 'pink' : ghost.id === 'inky' ? 'cyan' : 'orange'}-500`); |
| ghost.element.classList.add('bg-blue-500'); |
| } |
| }); |
| |
| |
| if (scaredTimer) clearTimeout(scaredTimer); |
| scaredTimer = setTimeout(() => { |
| scaredGhosts = false; |
| ghosts.forEach(ghost => { |
| if (!ghost.isEaten) { |
| ghost.isScared = false; |
| ghost.element.classList.remove('bg-blue-500'); |
| ghost.element.classList.add(`bg-${ghost.id === 'blinky' ? 'red' : ghost.id === 'pinky' ? 'pink' : ghost.id === 'inky' ? 'cyan' : 'orange'}-500`); |
| } |
| }); |
| }, 10000); |
| } |
| } |
| |
| |
| if (fruit && fruit.x === pacmanCellX && fruit.y === pacmanCellY) { |
| |
| document.getElementById('game-board').removeChild(fruit.element); |
| fruit = null; |
| score += 100; |
| document.getElementById('score').textContent = score; |
| |
| |
| pacmanBoost = true; |
| if (pacmanBoostTimer) clearTimeout(pacmanBoostTimer); |
| pacmanBoostTimer = setTimeout(() => { |
| pacmanBoost = false; |
| }, FRUIT_DURATION); |
| |
| |
| if (!scaredGhosts) { |
| scaredGhosts = true; |
| ghosts.forEach(ghost => { |
| if (!ghost.isEaten) { |
| ghost.isScared = true; |
| ghost.element.classList.remove(`bg-${ghost.id === 'blinky' ? 'red' : ghost.id === 'pinky' ? 'pink' : ghost.id === 'inky' ? 'cyan' : 'orange'}-500`); |
| ghost.element.classList.add('bg-blue-500'); |
| } |
| }); |
| if (scaredTimer) clearTimeout(scaredTimer); |
| scaredTimer = setTimeout(() => { |
| scaredGhosts = false; |
| ghosts.forEach(ghost => { |
| if (!ghost.isEaten) { |
| ghost.isScared = false; |
| ghost.element.classList.remove('bg-blue-500'); |
| ghost.element.classList.add(`bg-${ghost.id === 'blinky' ? 'red' : ghost.id === 'pinky' ? 'pink' : ghost.id === 'inky' ? 'cyan' : 'orange'}-500`); |
| } |
| }); |
| }, FRUIT_DURATION); |
| } |
| |
| startFruitAppearance(); |
| } |
| |
| |
| ghosts.forEach(ghost => { |
| const ghostX = Math.round(ghost.x); |
| const ghostY = Math.round(ghost.y); |
| |
| if (ghostX === pacmanCellX && ghostY === pacmanCellY) { |
| if (ghost.isScared && pacmanBoost) { |
| |
| ghost.isScared = false; |
| ghost.isEaten = true; |
| ghost.element.classList.remove('bg-blue-500', 'bg-white'); |
| ghost.element.classList.add('bg-gray-400'); |
| score += 200; |
| document.getElementById('score').textContent = score; |
| } else if (!ghost.isEaten) { |
| |
| lives--; |
| if (lives <= 0) { |
| gameOver(); |
| } else { |
| |
| resetPositions(); |
| } |
| } |
| } |
| }); |
| } |
| |
| |
| function resetPositions() { |
| pacman = { x: 14, y: 23, direction: 'right', nextDirection: 'right' }; |
| document.getElementById('pacman').style.left = `${pacman.x * CELL_SIZE}px`; |
| document.getElementById('pacman').style.top = `${pacman.y * CELL_SIZE}px`; |
| document.getElementById('pacman').style.transform = 'rotate(0deg)'; |
| |
| ghosts.forEach(ghost => { |
| if (ghost.id === 'blinky' || ghost.id === 'pinky') { |
| ghost.x = ghost.id === 'blinky' ? 13 : 14; |
| ghost.y = 11; |
| } else { |
| ghost.x = ghost.id === 'inky' ? 13 : 14; |
| ghost.y = 14; |
| } |
| |
| ghost.direction = 'up'; |
| ghost.isScared = false; |
| ghost.isEaten = false; |
| ghost.element.classList.remove('bg-blue-500', 'bg-gray-400', 'bg-white'); |
| ghost.element.classList.add(`bg-${ghost.id === 'blinky' ? 'red' : ghost.id === 'pinky' ? 'pink' : ghost.id === 'inky' ? 'cyan' : 'orange'}-500`); |
| ghost.element.style.left = `${ghost.x * CELL_SIZE}px`; |
| ghost.element.style.top = `${ghost.y * CELL_SIZE}px`; |
| }); |
| |
| |
| scaredGhosts = false; |
| if (scaredTimer) clearTimeout(scaredTimer); |
| pacmanBoost = false; |
| if (pacmanBoostTimer) clearTimeout(pacmanBoostTimer); |
| } |
| |
| |
| function gameOver() { |
| gameRunning = false; |
| document.getElementById('final-score').textContent = score; |
| document.getElementById('game-over').classList.remove('hidden'); |
| document.getElementById('restart-btn').classList.remove('hidden'); |
| if (fruitTimer) clearTimeout(fruitTimer); |
| } |
| |
| |
| function updateDisplay() { |
| |
| const pacmanElement = document.getElementById('pacman'); |
| pacmanElement.style.clipPath = 'polygon(50% 50%, 100% 0%, 100% 100%)'; |
| |
| |
| ghosts.forEach(ghost => { |
| if (ghost.isScared) { |
| |
| const remainingScaredTime = scaredTimer ? parseInt((scaredTimer._idleTimeout - scaredTimer._idleStart) / 1000) : 0; |
| if (remainingScaredTime <= 3 && Date.now() % 200 < 100) { |
| ghost.element.classList.remove('bg-blue-500'); |
| ghost.element.classList.add('bg-white'); |
| } else { |
| ghost.element.classList.remove('bg-white'); |
| ghost.element.classList.add('bg-blue-500'); |
| } |
| } |
| }); |
| } |
| |
| |
| function startGame() { |
| document.getElementById('start-screen').classList.add('hidden'); |
| initGame(); |
| } |
| |
| |
| document.addEventListener('keydown', (e) => { |
| if (e.key === 'Enter' && !gameRunning && !document.getElementById('start-screen').classList.contains('hidden')) { |
| startGame(); |
| } |
| |
| if (!gameRunning) return; |
| |
| switch (e.key) { |
| case 'ArrowLeft': |
| pacman.nextDirection = 'left'; |
| break; |
| case 'ArrowRight': |
| pacman.nextDirection = 'right'; |
| break; |
| case 'ArrowUp': |
| pacman.nextDirection = 'up'; |
| break; |
| case 'ArrowDown': |
| pacman.nextDirection = 'down'; |
| break; |
| } |
| }); |
| |
| document.getElementById('restart-btn').addEventListener('click', initGame); |
| document.getElementById('game-over-restart').addEventListener('click', () => { |
| document.getElementById('game-over').classList.add('hidden'); |
| initGame(); |
| }); |
| |
| |
| document.getElementById('start-screen').addEventListener('click', startGame); |
| }); |
| </script> |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - <a href="https://enzostvs-deepsite.hf.space?remix=alvesrt/pac-man" style="color: #fff;text-decoration: underline;" target="_blank" >🧬 Remix</a></p></body> |
| </html> |