WEBLEB
Início
Editor
Entrar
Pro
Português
English
Français
Español
Português
Deutsch
Italiano
हिंदी
Mini jogo Pac-Man HTML Canvas JavaScript
33
iroger7
Abrir no Editor
Publique Seu Código
Recomendado
28 August 2025
Exemplo de código HTML da página de login em turco
16 November 2024
Cartão Gradiente HTML
4 December 2025
Botão animado em HTML com SVG e texto
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