WEBLEB
Home
Editor
Accedi
Pro
Italiano
English
Français
Español
Português
Deutsch
Italiano
हिंदी
Mini Pac-Man Game HTML Canvas JavaScript
35
iroger7
Apri nell'Editor
Pubblica il Tuo Codice
Consigliato
13 September 2025
Animazione della barra di caricamento CSS HTML
10 July 2025
Esempio HTML della schermata di caricamento animata CSS
22 August 2025
Commento segnaposto codice HTML
HTML
Copy
Mini Pac‑Man — Fixed Lower Area
Score:
0
Lives:
3
Start
Mini Pac‑Man
Use arrow keys to move. Eat all dots to win. Avoid ghosts.
Play
CSS
Copy
/* Replace with your CSS Code (Leave empty if not needed) */
JS
Copy
<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width,initial-scale=1" /> <title>Mini Pac‑Man — Demo</title> <style> :root{ --bg:#000; --wall:#0d4f66; --dot:#ffd54f; --pac:#ffeb3b; --ghost:#ff6b6b; --text:#fff; } html,body{height:100%;margin:0;font-family:system-ui,-apple-system,Segoe UI,Roboto,'Helvetica Neue',Arial;background:#111;color:var(--text)} .wrap{min-height:100%;display:flex;align-items:center;justify-content:center;padding:18px;box-sizing:border-box} .game{ width:560px;height:620px;background:linear-gradient(#071428,#001021);border-radius:10px;box-shadow:0 10px 30px rgba(0,0,0,0.6);position:relative;overflow:hidden; display:flex;flex-direction:column;align-items:center;padding:12px; } canvas{background:var(--bg);border-radius:6px} .ui{width:100%;display:flex;justify-content:space-between;align-items:center;color:var(--text);padding:6px 10px} .panel{background:rgba(255,255,255,0.04);padding:8px 12px;border-radius:8px} button{background:#1976d2;color:white;border:none;padding:8px 12px;border-radius:8px;font-weight:700;cursor:pointer} .overlay{ position:absolute;inset:0;display:flex;align-items:center;justify-content:center;pointer-events:auto; } .panelBig{background:rgba(0,0,0,0.7);padding:18px;border-radius:12px;color:var(--text);text-align:center} @media (max-width:640px){ .game{width:360px;height:520px} canvas{width:320px;height:320px} } </style> </head> <body> <div class="wrap"> <div class="game" id="gameRoot" role="application" aria-label="Mini Pac-Man game"> <div class="ui"> <div class="panel">Score: <span id="score">0</span></div> <div class="panel">Lives: <span id="lives">3</span></div> <div><button id="startBtn">Start</button></div> </div> <canvas id="canvas" width="560" height="560" aria-hidden="false"></canvas> <div class="overlay" id="overlay" style="display:flex"> <div class="panelBig"> <h2 style="margin:0 0 8px 0">Mini Pac‑Man</h2> <p style="margin:0 0 12px 0">Use arrow keys to move. Eat all dots to win. Avoid ghosts.</p> <button id="overlayStart">Play</button> </div> </div> </div> </div> <script> /* Mini Pac‑Man - Single HTML file for classroom/demo use. - Simplified mechanics: grid-based movement, dots, 2 ghosts, basic collision. - Expandable: add power pellets, levels, sound, more ghosts. */ (function(){ const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); const startBtn = document.getElementById('startBtn'); const overlay = document.getElementById('overlay'); const overlayStart = document.getElementById('overlayStart'); const scoreLabel = document.getElementById('score'); const livesLabel = document.getElementById('lives'); // Grid settings const COLS = 28; // classic Pac-Man uses 28x31; we'll use 28x28 for square canvas const ROWS = 28; const TILE = Math.floor(canvas.width / COLS); const W = TILE * COLS; const H = TILE * ROWS; canvas.width = W; canvas.height = H; // Colors const COLORS = { wall: '#0d4f66', floor: '#071428', dot: '#ffd54f', pac: '#ffeb3b', ghost: '#ff6b6b', frightened: '#7fd3ff' }; // Game state let map = []; // 2D array: 0=floor,1=wall,2=dot let pac = { x: 14, y: 20, dir: {x:0,y:0}, nextDir: {x:0,y:0}, speed:1 }; let ghosts = []; let score = 0; let lives = 3; let running = false; let lastTime = 0; // Build a simple maze layout (0 floor, 1 wall). This is a small hand-crafted maze pattern. const raw = [ "1111111111111111111111111111", "1000000000110000000000000001", "1011111110110111111110111101", "1020000010000001000000010201", "1010111011111101111101010101", "1010111010000101000101010101", "1000000010110101010100000001", "1011111010110101010111111101", "1000000010000000000100000001", "1011111011111101111101111101", "1010000010000101000101000101", "1010111110110101010101110101", "1010000010000101000100000101", "1011111010111101111101111101", "1000000010000000000100000001", "1011111010110111110111111101", "1000000010110000000100000001", "1011111010111111110111111101", "1000000000000000000000000001", "1011111111111111111111111101", "1000000000000000000000000001", "1111111111111111111111111111", "1000000000000000000000000001", "1011111111111111111111111101", "1000000000000000000000000001", "1011111111111111111111111101", "1000000000000000000000000001", "1111111111111111111111111111" ]; function initMap(){ map = []; for (let y=0;y<ROWS;y++){ const row = []; const str = raw[y] || raw[raw.length-1]; for (let x=0;x<COLS;x++){ const ch = str[x] || '1'; if (ch === '1') row.push(1); // wall else if (ch === '0') row.push(2); // dot else if (ch === '2') row.push(0); // empty space (useful for tunnels/spawn) else row.push(1); } map.push(row); } } function resetEntities(){ pac.x = 14; pac.y = 20; pac.dir = {x:0,y:0}; pac.nextDir = {x:0,y:0}; ghosts = [ { x: 13, y: 11, dir:{x:0,y:0}, color:'#ff6b6b', mode:'chase' }, { x: 14, y: 11, dir:{x:0,y:0}, color:'#6b8cff', mode:'chase' } ]; } function startGame(){ initMap(); resetEntities(); score = 0; lives = 3; running = true; overlay.style.display = 'none'; scoreLabel.textContent = score; livesLabel.textContent = lives; lastTime = performance.now(); requestAnimationFrame(loop); } function endRound(){ lives--; livesLabel.textContent = lives; if (lives <= 0){ running = false; overlay.querySelector('.panelBig').innerHTML = '<h2 style="margin:0 0 8px 0">Game Over</h2><p style="margin:0 0 12px 0">Score: '+score+'</p><button id="playAgain">Play Again</button>'; overlay.style.display = 'flex'; document.getElementById('playAgain').addEventListener('click', ()=>startGame()); } else { resetEntities(); } } // Input window.addEventListener('keydown', (e)=>{ if (!running && (e.key === 'Enter' || e.key === ' ')) startGame(); const dir = keyToDir(e.key); if (dir) { pac.nextDir = dir; e.preventDefault(); } }); function keyToDir(k){ if (k === 'ArrowUp') return {x:0,y:-1}; if (k === 'ArrowDown') return {x:0,y:1}; if (k === 'ArrowLeft') return {x:-1,y:0}; if (k === 'ArrowRight') return {x:1,y:0}; return null; } // Movement helpers function canMoveTo(x,y){ if (y<0 || y>=ROWS || x<0 || x>=COLS) return false; return map[y][x] !== 1; } function update(dt){ // Pac-Man movement: grid-based with simple interpolation // Try to change direction if possible const nextX = pac.x + pac.nextDir.x; const nextY = pac.y + pac.nextDir.y; if (canMoveTo(nextX, nextY)){ pac.dir = pac.nextDir; } const targetX = pac.x + pac.dir.x; const targetY = pac.y + pac.dir.y; if (canMoveTo(targetX, targetY)){ pac.x = targetX; pac.y = targetY; } else { // blocked, stop pac.dir = {x:0,y:0}; } // collect dots if (map[pac.y][pac.x] === 2){ map[pac.y][pac.x] = 0; score += 10; scoreLabel.textContent = score; // check win: any dots left? if (!map.some(row => row.includes(2))){ running = false; overlay.querySelector('.panelBig').innerHTML = '<h2 style="margin:0 0 8px 0">You Win!</h2><p style="margin:0 0 12px 0">Score: '+score+'</p><button id="playAgain">Play Again</button>'; overlay.style.display = 'flex'; document.getElementById('playAgain').addEventListener('click', ()=>startGame()); } } // simple ghost AI: random valid direction, biased toward Pac-Man for (let g of ghosts){ if (Math.random() < 0.25){ // occasionally choose a new direction toward Pac const dx = pac.x - g.x; const dy = pac.y - g.y; let dir; if (Math.abs(dx) > Math.abs(dy)) dir = {x: Math.sign(dx), y:0}; else dir = {x:0, y: Math.sign(dy)}; const nx = g.x + dir.x, ny = g.y + dir.y; if (canMoveTo(nx,ny)) g.dir = dir; else { // pick random valid direction const opts = [{x:1,y:0},{x:-1,y:0},{x:0,y:1},{x:0,y:-1}].filter(d=>canMoveTo(g.x+d.x,g.y+d.y)); if (opts.length) g.dir = opts[Math.floor(Math.random()*opts.length)]; } } // move const gx = g.x + g.dir.x, gy = g.y + g.dir.y; if (canMoveTo(gx,gy)) { g.x = gx; g.y = gy; } } // collisions for (let g of ghosts){ if (g.x === pac.x && g.y === pac.y){ endRound(); break; } } } function draw(){ // background ctx.fillStyle = COLORS.floor; ctx.fillRect(0,0,W,H); // draw map for (let y=0;y<ROWS;y++){ for (let x=0;x<COLS;x++){ const v = map[y][x]; const px = x * TILE, py = y * TILE; if (v === 1){ // wall ctx.fillStyle = COLORS.wall; ctx.fillRect(px, py, TILE, TILE); // small bevel ctx.fillStyle = shadeColor(COLORS.wall, -10); ctx.fillRect(px+2, py+2, TILE-4, TILE-4); } else { // dot if (v === 2){ ctx.fillStyle = COLORS.dot; const r = Math.max(2, TILE * 0.12); ctx.beginPath(); ctx.arc(px + TILE/2, py + TILE/2, r, 0, Math.PI*2); ctx.fill(); } } } } // draw Pac-Man (simple circle with mouth indicating direction) const cx = pac.x * TILE + TILE/2; const cy = pac.y * TILE + TILE/2; ctx.fillStyle = COLORS.pac; // mouth angle based on dir let angle = 0.25; let start = 0.25*Math.PI, end = -0.25*Math.PI; if (pac.dir.x === 1) { start = 0.25*Math.PI; end = -0.25*Math.PI; } if (pac.dir.x === -1) { start = Math.PI+0.25*Math.PI; end = Math.PI-0.25*Math.PI; } if (pac.dir.y === -1) { start = -0.25*Math.PI; end = -0.75*Math.PI; } if (pac.dir.y === 1) { start = 0.75*Math.PI; end = 0.25*Math.PI; } // if stationary, small chomping if (pac.dir.x===0 && pac.dir.y===0){ start = 0.25*Math.PI; end = -0.25*Math.PI; } ctx.beginPath(); ctx.moveTo(cx,cy); ctx.arc(cx,cy, TILE*0.42, start, end, false); ctx.closePath(); ctx.fill(); // draw ghosts for (let g of ghosts){ const gx = g.x * TILE + TILE/2; const gy = g.y * TILE + TILE/2; const r = TILE*0.42; // body ctx.beginPath(); ctx.fillStyle = g.color; ctx.arc(gx, gy, r, Math.PI, 0, false); ctx.rect(gx - r, gy, r*2, r); ctx.fill(); // eyes ctx.fillStyle = '#fff'; ctx.beginPath(); ctx.arc(gx - r*0.3, gy - r*0.15, r*0.18, 0, Math.PI*2); ctx.arc(gx + r*0.3, gy - r*0.15, r*0.18, 0, Math.PI*2); ctx.fill(); ctx.fillStyle = '#000'; ctx.beginPath(); ctx.arc(gx - r*0.3, gy - r*0.15, r*0.08, 0, Math.PI*2); ctx.arc(gx + r*0.3, gy - r*0.15, r*0.08, 0, Math.PI*2); ctx.fill(); } } function loop(now){ const dt = Math.min(200, now - lastTime); if (running){ // update at a fixed-ish tick rate: move once every 140ms // accumulate time-based ticks tickAccumulator += dt; while (tickAccumulator > tickInterval){ update(tickInterval); tickAccumulator -= tickInterval; } } draw(); lastTime = now; requestAnimationFrame(loop); } // simple shading helper function shadeColor(col, percent) { const num = parseInt(col.replace('#',''),16); const r = Math.min(255, Math.max(0, (num>>16) + percent)); const g = Math.min(255, Math.max(0, ((num>>8)&0x00FF) + percent)); const b = Math.min(255, Math.max(0, (num&0x0000FF) + percent)); return '#' + ( (1<<24) + (r<<16) + (g<<8) + b ).toString(16).slice(1); } // Timing for grid ticks let tickAccumulator = 0; const tickInterval = 140; // ms per grid movement // Start/pause controls startBtn.addEventListener('click', ()=>{ if (!running) startGame(); }); overlayStart.addEventListener('click', startGame); // Initialize initMap(); resetEntities(); draw(); // Accessibility: allow clicking on canvas to move (simple direction control) canvas.addEventListener('click', (e)=>{ const rect = canvas.getBoundingClientRect(); const mx = e.clientX - rect.left; const my = e.clientY - rect.top; const dx = mx - (pac.x * TILE + TILE/2); const dy = my - (pac