Discussion

Créez un jeu d'arcade Breakout complet en HTML

De Wikiprompt, l’encyclopédie libre de prompts

Eyisha Zyer
Contribué parEyisha ZyerXSource

11 juil. 2026

Créez un jeu d'arcade Breakout complet en HTML Voici une traduction française de votre demande, en préservant tous les éléments techniques : --- **Prompt complet pour générer un jeu Breakout fonctionnel dans un seul fichier HTML :** Créez un jeu Breakout entièrement fonctionnel dans un seul fichier HTML autonome. Le jeu doit inclure les éléments suivants : **Gameplay :** - Une raquette contrôlée par le joueur en bas de l'écran - Une balle qui rebondit sur la raquette et les murs - Une rangée de briques destructibles en haut - Le joueur gagne des points en cassant les briques - Le joueur perd une vie si la balle tombe en bas - Le jeu se termine quand toutes les vies sont perdues ou que toutes les briques sont détruites - Augmentation progressive de la vitesse de la balle **Contrôles :** - Souris : déplacer la raquette horizontalement - Clavier : flèches gauche/droite pour déplacer la raquette - Barre d'espace : lancer la balle au début - Touche P : pause - Touche R : redémarrer **Visuels :** - Fond sombre avec un dégradé subtil - Raquette avec un dégradé de couleurs - Balle avec une traînée lumineuse - Briques de différentes couleurs selon leur résistance (rouge, orange, jaune, vert, bleu) - Effets de particules lors de la destruction des briques - Affichage du score, des vies et du niveau en haut **Audio :** - Sons générés par Web Audio API (pas de fichiers externes) - Son de rebond de la balle sur la raquette - Son de rebond sur les murs - Son de destruction de brique - Son de perte de vie - Son de victoire **Technique :** - Canvas HTML5 pour le rendu - Boucle de jeu avec requestAnimationFrame - Détection de collision précise entre la balle et les objets - Gestion des états du jeu (menu, jeu, pause, game over, victoire) - Responsive design qui s'adapte à la taille de l'écran - Code commenté et organisé en sections claires **Bonus :** - Briques spéciales avec des effets (élargir la raquette, balle multiple, vie supplémentaire) - Système de niveaux avec difficulté croissante - Meilleur score sauvegardé dans le localStorage Le code doit être autonome, sans dépendances externes, et fonctionner dans tous les navigateurs modernes.

Contenu du PromptEnregistrer

🌐
<!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; } body { background: #0a0a1a; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; overflow: hidden; user-select: none; } #gameContainer { position: relative; width: 800px; max-width: 95vw; aspect-ratio: 4/3; border-radius: 12px; overflow: hidden; box-shadow: 0 0 40px rgba(0, 200, 255, 0.2), 0 0 80px rgba(0, 200, 255, 0.1); background: #0d0d2b; } canvas { display: block; width: 100%; height: 100%; background: linear-gradient(180deg, #0d0d2b 0%, #1a1a3e 100%); } .overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: flex; flex-direction: column; justify-content: center; align-items: center; background: rgba(10, 10, 30, 0.85); backdrop-filter: blur(5px); z-index: 10; transition: opacity 0.3s; } .overlay.hidden { opacity: 0; pointer-events: none; } .overlay h1 { font-size: 3rem; color: #00e5ff; text-shadow: 0 0 20px rgba(0, 229, 255, 0.5); margin-bottom: 20px; letter-spacing: 4px; } .overlay h2 { font-size: 2rem; color: #ff6b6b; text-shadow: 0 0 15px rgba(255, 107, 107, 0.5); margin-bottom: 20px; } .overlay p { color: #aaa; font-size: 1.2rem; margin: 10px 0; } .overlay .score-final { font-size: 2.5rem; color: #ffd700; text-shadow: 0 0 20px rgba(255, 215, 0, 0.5); margin: 20px 0; } .overlay .btn { background: linear-gradient(135deg, #00e5ff, #0077ff); border: none; color: white; padding: 12px 30px; font-size: 1.2rem; border-radius: 30px; cursor: pointer; margin-top: 20px; transition: transform 0.2s, box-shadow 0.2s; box-shadow: 0 0 20px rgba(0, 229, 255, 0.3); } .overlay .btn:hover { transform: scale(1.05); box-shadow: 0 0 30px rgba(0, 229, 255, 0.5); } .overlay .btn:active { transform: scale(0.95); } .controls-info { color: #888; font-size: 0.9rem; margin-top: 20px; text-align: center; line-height: 1.6; } .controls-info span { color: #00e5ff; } #pauseOverlay { background: rgba(10, 10, 30, 0.7); } #pauseOverlay h1 { font-size: 2.5rem; color: #ffd700; } #winOverlay h1 { color: #00ff88; text-shadow: 0 0 20px rgba(0, 255, 136, 0.5); } #gameOverOverlay h1 { color: #ff4444; text-shadow: 0 0 20px rgba(255, 68, 68, 0.5); } .particle { position: absolute; pointer-events: none; border-radius: 50%; animation: particleAnim 0.6s ease-out forwards; } @keyframes particleAnim { 0% { transform: scale(1); opacity: 1; } 100% { transform: scale(0); opacity: 0; } } .heart { color: #ff4444; font-size: 1.5rem; text-shadow: 0 0 10px rgba(255, 68, 68, 0.5); } </style> </head> <body> <div id="gameContainer"> <canvas id="gameCanvas"></canvas> <!-- Start Overlay --> <div class="overlay" id="startOverlay"> <h1>NEON BREAKOUT</h1> <p>Break all the bricks!</p> <button class="btn" id="startBtn">Press Space to Start</button> <div class="controls-info"> <span>← →</span> or <span>Mouse</span> to move<br> <span>Space</span> to launch ball<br> <span>P</span> to pause </div> </div> <!-- Pause Overlay --> <div class="overlay hidden" id="pauseOverlay"> <h1>PAUSED</h1> <p>Press P to resume</p> </div> <!-- Game Over Overlay --> <div class="overlay hidden" id="gameOverOverlay"> <h1>GAME OVER</h1> <div class="score-final" id="finalScore">0</div> <button class="btn" id="restartBtn">Play Again</button> </div> <!-- Win Overlay --> <div class="overlay hidden" id="winOverlay"> <h1>YOU WIN!</h1> <div class="score-final" id="winScore">0</div> <button class="btn" id="nextLevelBtn">Next Level</button> </div> </div> <script> const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); const container = document.getElementById('gameContainer'); // Set canvas size const WIDTH = 800; const HEIGHT = 600; canvas.width = WIDTH; canvas.height = HEIGHT; // Game state let gameState = 'start'; // start, playing, paused, gameover, win let score = 0; let lives = 3; let level = 1; let highScore = 0; // Paddle const paddle = { width: 100, height: 15, x: WIDTH / 2 - 50, y: HEIGHT - 40, speed: 8, color: '#00e5ff' }; // Ball const ball = { x: WIDTH / 2, y: HEIGHT - 60, radius: 8, dx: 4, dy: -4, speed: 4, launched: false, color: '#ffffff' }; // Bricks let bricks = []; const brickRows = 5; const brickCols = 8; const brickWidth = 70; const brickHeight = 20; const brickPadding = 10; const brickOffsetTop = 50; const brickOffsetLeft = (WIDTH - (brickCols * (brickWidth + brickPadding) - brickPadding)) / 2; // Colors for bricks const brickColors = [ '#ff6b6b', '#ffa500', '#ffd700', '#00ff88', '#00e5ff' ]; // Particles let particles = []; // Audio context let audioCtx = null; // Keyboard state const keys = {}; // Initialize audio function initAudio() { if (!audioCtx) { audioCtx = new (window.AudioContext || window.webkitAudioContext)(); } } // Sound effects function playSound(freq, duration, type = 'sine', volume = 0.3) { if (!audioCtx) return; const oscillator = audioCtx.createOscillator(); const gainNode = audioCtx.createGain(); oscillator.connect(gainNode); gainNode.connect(audioCtx.destination); oscillator.frequency.value = freq; oscillator.type = type; gainNode.gain.setValueAtTime(volume, audioCtx.currentTime); gainNode.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + duration); oscillator.start(); oscillator.stop(audioCtx.currentTime + duration); } function playBounceSound() { playSound(200, 0.1, 'square', 0.2); } function playBrickSound() { playSound(500 + Math.random() * 200, 0.2, 'triangle', 0.3); } function playGameOverSound() { playSound(300, 0.5, 'sawtooth', 0.3); setTimeout(() => playSound(200, 0.5, 'sawtooth', 0.3), 200); setTimeout(() => playSound(100, 0.8, 'sawtooth', 0.3), 400); } function playWinSound() { playSound(523, 0.2, 'sine', 0.3); setTimeout(() => playSound(659, 0.2, 'sine', 0.3), 200); setTimeout(() => playSound(784, 0.3, 'sine', 0.3), 400); } // Create bricks function createBricks() { bricks = []; for (let row = 0; row < brickRows; row++) { for (let col = 0; col < brickCols; col++) { bricks.push({ x: brickOffsetLeft + col * (brickWidth + brickPadding), y: brickOffsetTop + row * (brickHeight + brickPadding), width: brickWidth, height: brickHeight, color: brickColors[row], alive: true, row: row }); } } } // Reset ball function resetBall() { ball.x = WIDTH / 2; ball.y = HEIGHT - 60; ball.dx = 4; ball.dy = -4; ball.speed = 4; ball.launched = false; } // Reset paddle function resetPaddle() { paddle.x = WIDTH / 2 - paddle.width / 2; } // Particle effects function createParticles(x, y, color) { for (let i = 0; i < 8; i++) { const angle = Math.random() * Math.PI * 2; const speed = 2 + Math.random() * 3; particles.push({ x: x, y: y, dx: Math.cos(angle) * speed, dy: Math.sin(angle) * speed, size: 2 + Math.random() * 3, color: color, life: 1 }); } } // Update particles function updateParticles() { particles = particles.filter(p => p.life > 0); particles.forEach(p => { p.x += p.dx; p.y += p.dy; p.dy += 0.1; p.life -= 0.02; }); } // Draw particles function drawParticles() { particles.forEach(p => { ctx.globalAlpha = p.life; ctx.fillStyle = p.color; ctx.beginPath(); ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2); ctx.fill(); }); ctx.globalAlpha = 1; } // Collision detection function checkCollisions() { // Wall collisions if (ball.x - ball.radius < 0) { ball.dx = Math.abs(ball.dx); playBounceSound(); } if (ball.x + ball.radius > WIDTH) { ball.dx = -Math.abs(ball.dx); playBounceSound(); } if (ball.y - ball.radius < 0) { ball.dy = Math.abs(ball.dy); playBounceSound(); } // Paddle collision if (ball.dy > 0 && ball.y + ball.radius >= paddle.y && ball.y + ball.radius <= paddle.y + paddle.height && ball.x >= paddle.x - ball.radius && ball.x <= paddle.x + paddle.width + ball.radius) { // Calculate bounce angle based on where ball hits paddle const hitPos = (ball.x - paddle.x) / paddle.width; const angle = (hitPos - 0.5) * Math.PI / 3; const speed = Math.sqrt(ball.dx * ball.dx + ball.dy * ball.dy); ball.dx = Math.sin(angle) * speed; ball.dy = -Math.cos(angle) * speed; ball.y = paddle.y - ball.radius; playBounceSound(); } // Brick collisions for (let i = 0; i < bricks.length; i++) { const brick = bricks[i]; if (!brick.alive) continue; if (ball.x + ball.radius > brick.x && ball.x - ball.radius < brick.x + brick.width && ball.y + ball.radius > brick.y && ball.y - ball.radius < brick.y + brick.height) { brick.alive = false; score += 10; createParticles(brick.x + brick.width / 2, brick.y + brick.height / 2, brick.color); playBrickSound(); // Determine bounce direction const overlapLeft = ball.x + ball.radius - brick.x; const overlapRight = brick.x + brick.width - (ball.x - ball.radius); const overlapTop = ball.y + ball.radius - brick.y; const overlapBottom = brick.y + brick.height - (ball.y - ball.radius); const minOverlap = Math.min(overlapLeft, overlapRight, overlapTop, overlapBottom); if (minOverlap === overlapLeft || minOverlap === overlapRight) { ball.dx = -ball.dx; } else { ball.dy = -ball.dy; } // Check win condition if (bricks.every(b => !b.alive)) { gameState = 'win'; document.getElementById('winScore').textContent = score; document.getElementById('winOverlay').classList.remove('hidden'); playWinSound(); } break; } } // Ball falls below paddle if (ball.y > HEIGHT + 50) { lives--; if (lives <= 0) { gameState = 'gameover'; document.getElementById('finalScore').textContent = score; document.getElementById('gameOverOverlay').classList.remove('hidden'); playGameOverSound(); } else { resetBall(); resetPaddle(); } } } // Draw functions function drawPaddle() { // Glow effect ctx.shadowColor = paddle.color; ctx.shadowBlur = 20; const gradient = ctx.createLinearGradient(paddle.x, paddle.y, paddle.x, paddle.y + paddle.height); gradient.addColorStop(0, '#00ffff'); gradient.addColorStop(1, '#0077ff'); ctx.fillStyle = gradient; ctx.beginPath(); ctx.roundRect(paddle.x, paddle.y, paddle.width, paddle.height, 8); ctx.fill(); ctx.shadowBlur = 0; } function drawBall() { ctx.shadowColor = '#ffffff'; ctx.shadowBlur = 15; const gradient = ctx.createRadialGradient( ball.x - 2, ball.y - 2, 1, ball.x, ball.y, ball.radius ); gradient.addColorStop(0, '#ffffff'); gradient.addColorStop(1, '#00e5ff'); ctx.fillStyle = gradient; ctx.beginPath(); ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2); ctx.fill(); ctx.shadowBlur = 0; } function drawBricks() { bricks.forEach(brick => { if (!brick.alive) return; ctx.shadowColor = brick.color; ctx.shadowBlur = 10; const gradient = ctx.createLinearGradient(brick.x, brick.y, brick.x, brick.y + brick.height); gradient.addColorStop(0, brick.color); gradient.addColorStop(1, shadeColor(brick.color, -30)); ctx.fillStyle = gradient; ctx.beginPath(); ctx.roundRect(brick.x, brick.y, brick.width, brick.height, 4); ctx.fill(); // Highlight ctx.fillStyle = 'rgba(255,255,255,0.2)'; ctx.beginPath(); ctx.roundRect(brick.x + 2, brick.y + 2, brick.width - 4, brick.height / 2, 3); ctx.fill(); ctx.shadowBlur = 0; }); } function drawHUD() { // Score ctx.fillStyle = '#ffffff'; ctx.font = 'bold 20px "Segoe UI", sans-serif'; ctx.textAlign = 'left'; ctx.shadowColor = '#00e5ff'; ctx.shadowBlur = 10; ctx.fillText(`SCORE: ${score}`, 20, 35); ctx.shadowBlur = 0; // Level ctx.textAlign = 'center'; ctx.fillStyle = '#ffd700'; ctx.shadowColor = '#ffd700'; ctx.shadowBlur = 10; ctx.fillText(`LEVEL ${level}`, WIDTH / 2, 35); ctx.shadowBlur = 0; // Lives ctx.textAlign = 'right'; ctx.fillStyle = '#ff4444'; ctx.shadowColor = '#ff4444'; ctx.shadowBlur = 10; let hearts = ''; for (let i = 0; i < lives; i++) { hearts += '♥ '; } ctx.fillText(hearts, WIDTH - 20, 35); ctx.shadowBlur = 0; } function shadeColor(color, percent) { const num = parseInt(color.replace('#', ''), 16); const amt = Math.round(2.55 * percent); const R = Math.min(255, Math.max(0, (num >> 16) + amt)); const G = Math.min(255, Math.max(0, ((num >> 8) & 0x00FF) + amt)); const B = Math.min(255, Math.max(0, (num & 0x0000FF) + amt)); return `#${(0x1000000 + R * 0x10000 + G * 0x100 + B).toString(16).slice(1)}`; } // Update game function update() { if (gameState !== 'playing') return; // Move paddle with keyboard if (keys['ArrowLeft'] && paddle.x > 0) { paddle.x -= paddle.speed; } if (keys['ArrowRight'] && paddle.x + paddle.width < WIDTH) { paddle.x += paddle.speed; } // Launch ball if (ball.launched) { ball.x += ball.dx; ball.y += ball.dy; // Increase speed slightly over time const speed = Math.sqrt(ball.dx * ball.dx + ball.dy * ball.dy); if (speed < 8) { ball.dx *= 1.0005; ball.dy *= 1.0005; } } else { // Ball follows paddle ball.x = paddle.x + paddle.width / 2; ball.y = paddle.y - ball.radius - 2; } checkCollisions(); updateParticles(); } // Draw everything function draw() { ctx.clearRect(0, 0, WIDTH, HEIGHT); // Background grid ctx.strokeStyle = 'rgba(255,255,255,0.03)'; ctx.lineWidth = 1; for (let i = 0; i < WIDTH; i += 40) { ctx.beginPath(); ctx.moveTo(i, 0); ctx.lineTo(i, HEIGHT); ctx.stroke(); } for (let i = 0; i < HEIGHT; i += 40) { ctx.beginPath(); ctx.moveTo(0, i); ctx.lineTo(WIDTH, i); ctx.stroke(); } drawBricks(); drawPaddle(); drawBall(); drawParticles(); drawHUD(); } // Game loop function gameLoop() { update(); draw(); requestAnimationFrame(gameLoop); } // Event listeners document.addEventListener('keydown', (e) => { keys[e.key] = true; if (e.key === ' ') { e.preventDefault(); initAudio(); if (gameState === 'start') { gameState = 'playing'; document.getElementById('startOverlay').classList.add('hidden'); ball.launched = true; } else if (gameState === 'playing' && !ball.launched) { ball.launched = true; } } if (e.key === 'p' || e.key === 'P') { if (gameState === 'playing') { gameState = 'paused'; document.getElementById('pauseOverlay').classList.remove('hidden'); } else if (gameState === 'paused') { gameState = 'playing'; document.getElementById('pauseOverlay').classList.add('hidden'); } } }); document.addEventListener('keyup', (e) => { keys[e.key] = false; }); // Mouse control canvas.addEventListener('mousemove', (e) => { const rect = canvas.getBoundingClientRect(); const scaleX = WIDTH / rect.width; const mouseX = (e.clientX - rect.left) * scaleX; if (gameState === 'playing') { paddle.x = mouseX - paddle.width / 2; paddle.x = Math.max(0, Math.min(WIDTH - paddle.width, paddle.x)); } }); // Touch control canvas.addEventListener('touchmove', (e) => { e.preventDefault(); const rect = canvas.getBoundingClientRect(); const scaleX = WIDTH / rect.width; const touchX = (e.touches[0].clientX - rect.left) * scaleX; if (gameState === 'playing') { paddle.x = touchX - paddle.width / 2; paddle.x = Math.max(0, Math.min(WIDTH - paddle.width, paddle.x)); } }); // Button handlers document.getElementById('startBtn').addEventListener('click', () => { initAudio(); gameState = 'playing'; document.getElementById('startOverlay').classList.add('hidden'); ball.launched = true; }); document.getElementById('restartBtn').addEventListener('click', () => { score = 0; lives = 3; level = 1; createBricks(); resetBall(); resetPaddle(); gameState = 'playing'; document.getElementById('gameOverOverlay').classList.add('hidden'); ball.launched = true; }); document.getElementById('nextLevelBtn').addEventListener('click', () => { level++; lives = Math.min(5, lives + 1); createBricks(); resetBall(); resetPaddle(); ball.speed = 4 + (level - 1) * 0.5; gameState = 'playing'; document.getElementById('winOverlay').classList.add('hidden'); ball.launched = true; }); // Initialize game createBricks(); resetBall(); resetPaddle(); // Start game loop gameLoop(); </script> </body> </html>

Connectez-vous pour voir le prompt complet

Continuer avec:

En vous connectant, vous acceptez nos Conditions et Confidentialité

Utilisation

Ce prompt est conçu pour être utilisé avec coding. Copiez le contenu ci-dessus et collez-le dans votre outil d’IA préféré.

Pour de meilleurs résultats, personnalisez les espaces réservés (indiqués par des crochets ou des majuscules) selon vos besoins.

Références

Catégories :coding| twitter| breakout-game| html5-canvas

Discussion