Diskussion

Baue ein vollständiges Breakout-Arcade-Spiel in HTML

Von Wikiprompt, der freien Prompt-Enzyklopädie

Eyisha Zyer
Beigetragen vonEyisha ZyerXQuelle

11. Juli 2026

Baue ein vollständiges Breakout-Arcade-Spiel in HTML Ein umfassender Prompt zur Erstellung eines voll funktionsfähigen Breakout-Spiels in einer einzigen HTML-Datei, der Gameplay, Steuerung, visuelle Effekte, Audio und technische Details abdeckt.

Prompt-InhaltSpeichern

🌐
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>NEON BREAKOUT</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; user-select: none; } body { background: #0a0f1e; min-height: 100vh; display: flex; justify-content: center; align-items: center; font-family: 'Segoe UI', system-ui, sans-serif; touch-action: none; } .game-wrapper { background: #111827; border-radius: 24px; padding: 16px; box-shadow: 0 0 40px rgba(0, 255, 255, 0.15), 0 20px 40px rgba(0,0,0,0.8); border: 1px solid #2a3a5e; } canvas { display: block; width: 100%; max-width: 900px; height: auto; border-radius: 16px; background: #0b1322; box-shadow: inset 0 0 30px rgba(0,0,0,0.6), 0 0 20px rgba(0, 200, 255, 0.2); cursor: none; } .info-bar { display: flex; justify-content: space-between; align-items: center; padding: 12px 8px 4px 8px; color: #b3e0ff; font-weight: 600; letter-spacing: 1px; text-shadow: 0 0 8px #00ccff; } .info-item { display: flex; gap: 12px; background: #1e293b; padding: 6px 16px; border-radius: 40px; border: 1px solid #3b4b6b; box-shadow: 0 0 12px rgba(0,255,255,0.2); } .badge { background: #0f172a; padding: 4px 12px; border-radius: 30px; color: #7dd3fc; border: 1px solid #2c3e5e; } .btn-reset { background: #1e293b; border: 1px solid #4a6a9a; color: #a0d8ff; padding: 6px 18px; border-radius: 40px; font-weight: 700; cursor: pointer; transition: all 0.2s; box-shadow: 0 0 10px #00aaff33; } .btn-reset:hover { background: #2d3f5e; box-shadow: 0 0 20px #00ccff; color: white; } </style> </head> <body> <div style="display: flex; flex-direction: column; gap: 8px; width: min(900px, 95vw);"> <div class="info-bar"> <div class="info-item">🏆 <span id="scoreDisplay">0</span></div> <div class="info-item">❤️ <span id="livesDisplay">3</span> &nbsp; | &nbsp; LEVEL <span id="levelDisplay">1</span></div> <button class="btn-reset" id="restartBtn">↺ RESTART</button> </div> <canvas id="gameCanvas" width="900" height="600"></canvas> <div style="text-align: center; color: #5f7a9a; font-size: 14px; padding-top: 6px; letter-spacing: 1px;"> ← → / MOUSE MOVE · SPACE LAUNCH · P PAUSE </div> </div> <script> (function() { const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); const scoreSpan = document.getElementById('scoreDisplay'); const livesSpan = document.getElementById('livesDisplay'); const levelSpan = document.getElementById('levelDisplay'); // ---------- GAME STATE ---------- let gameState = 'START'; // START, PLAYING, PAUSED, GAMEOVER, WIN let score = 0; let lives = 3; let level = 1; let ballSpeedMultiplier = 1.0; // paddle const paddle = { width: 140, height: 16, x: 450 - 70, y: 560, color: '#00e5ff', targetX: 450 - 70, }; // ball const ball = { x: 450, y: 530, radius: 9, dx: 3.2, dy: -4.2, speed: 5.2, launched: false, }; // bricks grid let bricks = []; const brickRows = 6; const brickCols = 10; const brickWidth = 70; const brickHeight = 22; const brickPadding = 8; const brickOffsetTop = 60; const brickOffsetLeft = 55; // particles let particles = []; // power-ups (simple: multi-ball, wide paddle, slow) let activePowerUps = { multiBall: 0, widePaddle: 0, slowBall: 0, }; let extraBalls = []; // for multi-ball // audio (synthetic) const audioCtx = new (window.AudioContext || window.webkitAudioContext)(); function playTone(freq, duration, type = 'square', volume = 0.15) { if (audioCtx.state === 'suspended') audioCtx.resume(); const osc = audioCtx.createOscillator(); const gain = audioCtx.createGain(); osc.type = type; osc.frequency.value = freq; gain.gain.setValueAtTime(volume, audioCtx.currentTime); gain.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + duration); osc.connect(gain); gain.connect(audioCtx.destination); osc.start(); osc.stop(audioCtx.currentTime + duration); } // ---------- INIT BRICKS ---------- function createBricks() { bricks = []; const colors = ['#ff4d6d', '#ff8c42', '#ffd166', '#4cc9f0', '#b5179e', '#4895ef']; for (let r = 0; r < brickRows; r++) { for (let c = 0; c < brickCols; c++) { bricks.push({ x: brickOffsetLeft + c * (brickWidth + brickPadding), y: brickOffsetTop + r * (brickHeight + brickPadding), width: brickWidth, height: brickHeight, color: colors[r % colors.length], alive: true, glow: 0.8 + Math.random() * 0.4, }); } } } // ---------- RESET BALL & PADDLE ---------- function resetBall() { ball.launched = false; ball.x = paddle.x + paddle.width / 2; ball.y = paddle.y - 12; ball.dx = 3.2; ball.dy = -4.2; ball.speed = 5.2 * ballSpeedMultiplier; extraBalls = []; } function resetGame() { score = 0; lives = 3; level = 1; ballSpeedMultiplier = 1.0; paddle.width = 140; paddle.x = 450 - 70; paddle.targetX = paddle.x; createBricks(); resetBall(); activePowerUps = { multiBall: 0, widePaddle: 0, slowBall: 0 }; particles = []; gameState = 'START'; updateUI(); } // ---------- UI UPDATE ---------- function updateUI() { scoreSpan.textContent = score; livesSpan.textContent = lives; levelSpan.textContent = level; } // ---------- COLLISION & PHYSICS ---------- function ballBounce(ballObj) { // walls if (ballObj.x - ballObj.radius < 0) { ballObj.x = ballObj.radius; ballObj.dx = -ballObj.dx; playTone(300, 0.08, 'triangle', 0.1); } if (ballObj.x + ballObj.radius > canvas.width) { ballObj.x = canvas.width - ballObj.radius; ballObj.dx = -ballObj.dx; playTone(300, 0.08, 'triangle', 0.1); } if (ballObj.y - ballObj.radius < 0) { ballObj.y = ballObj.radius; ballObj.dy = -ballObj.dy; playTone(400, 0.08, 'triangle', 0.1); } // paddle collision if (ballObj.dy > 0 && ballObj.y + ballObj.radius >= paddle.y && ballObj.y + ballObj.radius <= paddle.y + paddle.height + 8 && ballObj.x >= paddle.x - ballObj.radius && ballObj.x <= paddle.x + paddle.width + ballObj.radius) { // angle based on hit position let hitPos = (ballObj.x - (paddle.x + paddle.width/2)) / (paddle.width/2); hitPos = Math.max(-0.8, Math.min(0.8, hitPos)); let angle = hitPos * 0.6; let speed = Math.hypot(ballObj.dx, ballObj.dy); ballObj.dx = speed * Math.sin(angle); ballObj.dy = -Math.abs(speed * Math.cos(angle)); ballObj.y = paddle.y - ballObj.radius - 1; playTone(500, 0.1, 'sine', 0.12); } // bricks collision for (let i = 0; i < bricks.length; i++) { const b = bricks[i]; if (!b.alive) continue; if (ballObj.x + ballObj.radius > b.x && ballObj.x - ballObj.radius < b.x + b.width && ballObj.y + ballObj.radius > b.y && ballObj.y - ballObj.radius < b.y + b.height) { b.alive = false; score += 10; // particle burst for (let p = 0; p < 14; p++) { particles.push({ x: b.x + b.width/2, y: b.y + b.height/2, vx: (Math.random() - 0.5) * 8, vy: (Math.random() - 0.5) * 8 - 2, life: 1.0, color: b.color, size: 3 + Math.random() * 5 }); } playTone(800 + Math.random() * 200, 0.12, 'square', 0.1); // determine bounce direction const overlapLeft = ballObj.x + ballObj.radius - b.x; const overlapRight = b.x + b.width - (ballObj.x - ballObj.radius); const overlapTop = ballObj.y + ballObj.radius - b.y; const overlapBottom = b.y + b.height - (ballObj.y - ballObj.radius); const minOverlap = Math.min(overlapLeft, overlapRight, overlapTop, overlapBottom); if (minOverlap === overlapLeft || minOverlap === overlapRight) { ballObj.dx = -ballObj.dx; } else { ballObj.dy = -ballObj.dy; } break; // only one brick per frame } } // check win if (bricks.every(b => !b.alive)) { gameState = 'WIN'; playTone(1200, 0.4, 'sine', 0.2); playTone(1600, 0.5, 'sine', 0.2); } } // ---------- UPDATE ---------- function update() { if (gameState !== 'PLAYING') return; // paddle movement (keyboard handled in event, but mouse target) paddle.x += (paddle.targetX - paddle.x) * 0.2; paddle.x = Math.max(0, Math.min(canvas.width - paddle.width, paddle.x)); // main ball if (!ball.launched) { ball.x = paddle.x + paddle.width/2; ball.y = paddle.y - 12; } else { ball.x += ball.dx * ballSpeedMultiplier; ball.y += ball.dy * ballSpeedMultiplier; ballBounce(ball); } // extra balls (multi-ball) for (let i = extraBalls.length - 1; i >= 0; i--) { const eb = extraBalls[i]; eb.x += eb.dx * ballSpeedMultiplier; eb.y += eb.dy * ballSpeedMultiplier; ballBounce(eb); if (eb.y - eb.radius > canvas.height + 20) { extraBalls.splice(i, 1); } } // ball lost condition if (ball.y - ball.radius > canvas.height + 20) { lives--; updateUI(); if (lives <= 0) { gameState = 'GAMEOVER'; playTone(200, 0.5, 'sawtooth', 0.2); } else { resetBall(); } } // extra balls lost for (let i = extraBalls.length - 1; i >= 0; i--) { if (extraBalls[i].y - extraBalls[i].radius > canvas.height + 20) { extraBalls.splice(i, 1); } } // particles for (let i = particles.length - 1; i >= 0; i--) { const p = particles[i]; p.x += p.vx; p.y += p.vy; p.vy += 0.15; p.life -= 0.02; if (p.life <= 0) particles.splice(i, 1); } // power-up timers (simplified) if (activePowerUps.widePaddle > 0) { activePowerUps.widePaddle--; if (activePowerUps.widePaddle === 0) paddle.width = 140; } if (activePowerUps.slowBall > 0) { activePowerUps.slowBall--; if (activePowerUps.slowBall === 0) ballSpeedMultiplier = 1.0; } if (activePowerUps.multiBall > 0) { activePowerUps.multiBall--; if (activePowerUps.multiBall === 0) extraBalls = []; } // level progression (simple: every 500 points) if (score > 0 && Math.floor(score / 500) > level - 1) { level = Math.floor(score / 500) + 1; levelSpan.textContent = level; ballSpeedMultiplier = 1.0 + (level - 1) * 0.1; // add some bricks back? no, just speed } } // ---------- RENDER ---------- function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); // background grid ctx.strokeStyle = '#1e2a44'; ctx.lineWidth = 0.5; for (let i = 0; i < canvas.width; i += 40) { ctx.beginPath(); ctx.moveTo(i, 0); ctx.lineTo(i, canvas.height); ctx.strokeStyle = '#1a2740'; ctx.stroke(); } for (let i = 0; i < canvas.height; i += 40) { ctx.beginPath(); ctx.moveTo(0, i); ctx.lineTo(canvas.width, i); ctx.strokeStyle = '#1a2740'; ctx.stroke(); } // bricks for (let b of bricks) { if (!b.alive) continue; const grad = ctx.createLinearGradient(b.x, b.y, b.x, b.y + b.height); grad.addColorStop(0, b.color); grad.addColorStop(1, '#1a1a3a'); ctx.fillStyle = grad; ctx.shadowColor = b.color; ctx.shadowBlur = 15; ctx.fillRect(b.x, b.y, b.width, b.height); ctx.shadowBlur = 0; ctx.strokeStyle = '#ffffff30'; ctx.strokeRect(b.x, b.y, b.width, b.height); } // paddle ctx.shadowColor = '#00e5ff'; ctx.shadowBlur = 20; ctx.fillStyle = '#00e5ff'; ctx.beginPath(); ctx.roundRect(paddle.x, paddle.y, paddle.width, paddle.height, 8); ctx.fill(); ctx.shadowBlur = 0; ctx.fillStyle = '#ffffff'; ctx.beginPath(); ctx.roundRect(paddle.x + 4, paddle.y + 2, paddle.width - 8, 4, 4); ctx.fill(); // ball (main) ctx.shadowColor = '#ffaa00'; ctx.shadowBlur = 20; ctx.fillStyle = '#ffd966'; ctx.beginPath(); ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2); ctx.fill(); ctx.shadowBlur = 0; // extra balls for (let eb of extraBalls) { ctx.fillStyle = '#ffaa66'; ctx.shadowColor = '#ff8800'; ctx.shadowBlur = 15; ctx.beginPath(); ctx.arc(eb.x, eb.y, ball.radius, 0, Math.PI * 2); ctx.fill(); ctx.shadowBlur = 0; } // particles for (let p of particles) { ctx.globalAlpha = Math.max(0, p.life); ctx.fillStyle = p.color; ctx.shadowColor = p.color; ctx.shadowBlur = 10; ctx.beginPath(); ctx.arc(p.x, p.y, p.size * p.life, 0, Math.PI * 2); ctx.fill(); } ctx.globalAlpha = 1; ctx.shadowBlur = 0; // overlays if (gameState === 'START') { ctx.fillStyle = '#000000aa'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = '#ffffff'; ctx.font = 'bold 42px "Segoe UI", sans-serif'; ctx.textAlign = 'center'; ctx.shadowColor = '#00ccff'; ctx.shadowBlur = 30; ctx.fillText('NEON BREAKOUT', canvas.width/2, 220); ctx.font = '24px sans-serif'; ctx.fillStyle = '#aaf0ff'; ctx.fillText('PRESS SPACE TO START', canvas.width/2, 320); ctx.shadowBlur = 0; } if (gameState === 'PAUSED') { ctx.fillStyle = '#00000088'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = '#ffffff'; ctx.font = 'bold 40px sans-serif'; ctx.fillText('⏸ PAUSED', canvas.width/2, 300); ctx.font = '20px sans-serif'; ctx.fillText('PRESS P TO RESUME', canvas.width/2, 360); } if (gameState === 'GAMEOVER') { ctx.fillStyle = '#000000bb'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = '#ff4d6d'; ctx.font = 'bold 46px sans-serif'; ctx.fillText('GAME OVER', canvas.width/2, 280); ctx.fillStyle = '#ffffff'; ctx.font = '24px sans-serif'; ctx.fillText(`SCORE: ${score}`, canvas.width/2, 340); ctx.fillText('CLICK RESTART', canvas.width/2, 400); } if (gameState === 'WIN') { ctx.fillStyle = '#000000aa'; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = '#ffd166'; ctx.font = 'bold 46px sans-serif'; ctx.fillText('🏆 YOU WIN!', canvas.width/2, 280); ctx.fillStyle = '#ffffff'; ctx.font = '24px sans-serif'; ctx.fillText(`SCORE: ${score}`, canvas.width/2, 340); } } // roundRect helper CanvasRenderingContext2D.prototype.roundRect = function(x, y, w, h, r) { if (w < 2 * r) r = w / 2; if (h < 2 * r) r = h / 2; this.moveTo(x + r, y); this.lineTo(x + w - r, y); this.quadraticCurveTo(x + w, y, x + w, y + r); this.lineTo(x + w, y + h - r); this.quadraticCurveTo(x + w, y + h, x + w - r, y + h); this.lineTo(x + r, y + h); this.quadraticCurveTo(x, y + h, x, y + h - r); this.lineTo(x, y + r); this.quadraticCurveTo(x, y, x + r, y); return this; }; // ---------- GAME LOOP ---------- function gameLoop() { update(); draw(); requestAnimationFrame(gameLoop); } // ---------- EVENT LISTENERS ---------- // mouse canvas.addEventListener('mousemove', (e) => { const rect = canvas.getBoundingClientRect(); const scaleX = canvas.width / rect.width; const mouseX = (e.clientX - rect.left) * scaleX; paddle.targetX = mouseX - paddle.width / 2; }); // keyboard window.addEventListener('keydown', (e) => { if (e.key === 'ArrowLeft') { paddle.targetX = Math.max(0, paddle.x - 30); e.preventDefault(); } if (e.key === 'ArrowRight') { paddle.targetX = Math.min(canvas.width - paddle.width, paddle.x + 30); e.preventDefault(); } if (e.key === ' ') { e.preventDefault(); if (gameState === 'START') { gameState = 'PLAYING'; ball.launched = true; playTone(600, 0.1, 'sine'); } else if (gameState === 'PLAYING' && !ball.launched) { ball.launched = true; playTone(600, 0.1, 'sine'); } } if (e.key === 'p' || e.key === 'P') { if (gameState === 'PLAYING') { gameState = 'PAUSED'; } else if (gameState === 'PAUSED') { gameState = 'PLAYING'; } } }); // restart button document.getElementById('restartBtn').addEventListener('click', () => { resetGame(); gameState = 'START'; }); // initial setup createBricks(); resetBall(); updateUI(); gameLoop(); // power-up simulation (random every 20 seconds) setInterval(() => { if (gameState !== 'PLAYING') return; const rand = Math.random(); if (rand < 0.4) { activePowerUps.widePaddle = 600; paddle.width = 200; } else if (rand < 0.7) { activePowerUps.slowBall = 500; ballSpeedMultiplier = 0.7; } else { if (extraBalls.length < 3) { for (let i = 0; i < 2; i++) { extraBalls.push({ x: ball.x, y: ball.y, dx: (Math.random() - 0.5) * 6, dy: -Math.random() * 5 - 2, radius: 8, }); } activePowerUps.multiBall = 300; } } }, 15000); })(); </script> </body> </html>

Melde dich an, um den vollständigen Prompt zu sehen

Weiter mit:

Mit der Anmeldung akzeptierst du unsere Nutzungsbedingungen und Datenschutz

Verwendung

Dieser Prompt ist für die Verwendung mit coding gedacht. Kopiere den Inhalt oben und füge ihn in dein bevorzugtes KI-Tool ein.

Für beste Ergebnisse passe die Platzhalter (eckige Klammern oder Großbuchstaben) an deine Anforderungen an.

Referenzen

Kategorien:coding| twitter| breakout-game| html5-canvas

Diskussion