Last active
May 25, 2025 06:33
-
-
Save Studio1HQ/9894bb119c357f65362c515b30b05004 to your computer and use it in GitHub Desktop.
Arkanoid Game Output Claude 4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!doctype html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| <title>DX BRICK BREAKER</title> | |
| <style> | |
| @import url("<https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&display=swap>"); | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| background: linear-gradient(135deg, #0a0a0a, #1a1a2e); | |
| font-family: "Orbitron", monospace; | |
| overflow: hidden; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| height: 100vh; | |
| } | |
| .arcade-cabinet { | |
| width: 600px; | |
| height: 800px; | |
| background: linear-gradient(145deg, #2a2a2a, #1a1a1a); | |
| border-radius: 20px 20px 0 0; | |
| box-shadow: 0 0 50px rgba(0, 255, 255, 0.3); | |
| position: relative; | |
| border: 3px solid #00ffff; | |
| } | |
| .screen-bezel { | |
| width: 520px; | |
| height: 580px; | |
| background: #000; | |
| margin: 40px auto 20px; | |
| border: 8px solid #333; | |
| border-radius: 10px; | |
| position: relative; | |
| box-shadow: inset 0 0 20px rgba(0, 255, 255, 0.2); | |
| } | |
| #gameCanvas { | |
| width: 100%; | |
| height: 100%; | |
| background: #000011; | |
| image-rendering: pixelated; | |
| } | |
| .controls { | |
| display: flex; | |
| justify-content: space-around; | |
| padding: 20px; | |
| background: linear-gradient(145deg, #1a1a1a, #2a2a2a); | |
| } | |
| .joystick, | |
| .buttons { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| } | |
| .joystick-base { | |
| width: 80px; | |
| height: 80px; | |
| background: radial-gradient(circle, #333, #111); | |
| border-radius: 50%; | |
| border: 4px solid #555; | |
| position: relative; | |
| } | |
| .joystick-stick { | |
| width: 20px; | |
| height: 20px; | |
| background: #ff0000; | |
| border-radius: 50%; | |
| position: absolute; | |
| top: 50%; | |
| left: 50%; | |
| transform: translate(-50%, -50%); | |
| border: 2px solid #fff; | |
| } | |
| .button { | |
| width: 60px; | |
| height: 60px; | |
| border-radius: 50%; | |
| border: 4px solid #333; | |
| margin: 5px; | |
| font-family: "Orbitron", monospace; | |
| font-weight: bold; | |
| cursor: pointer; | |
| transition: all 0.1s; | |
| } | |
| .launch-button { | |
| background: radial-gradient(circle, #44ff44, #00cc00); | |
| color: white; | |
| } | |
| .launch-button:active { | |
| transform: scale(0.95); | |
| box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.5); | |
| } | |
| .title { | |
| position: absolute; | |
| top: 10px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| color: #00ffff; | |
| font-size: 22px; | |
| font-weight: 900; | |
| text-shadow: 0 0 10px #00ffff; | |
| letter-spacing: 2px; | |
| } | |
| .score-display { | |
| position: absolute; | |
| top: 50px; | |
| left: 20px; | |
| color: #00ff00; | |
| font-size: 18px; | |
| font-weight: bold; | |
| text-shadow: 0 0 5px #00ff00; | |
| } | |
| .lives-display { | |
| position: absolute; | |
| top: 50px; | |
| right: 20px; | |
| color: #ff0000; | |
| font-size: 18px; | |
| font-weight: bold; | |
| text-shadow: 0 0 5px #ff0000; | |
| } | |
| .level-display { | |
| position: absolute; | |
| top: 75px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| color: #ffff00; | |
| font-size: 16px; | |
| font-weight: bold; | |
| text-shadow: 0 0 5px #ffff00; | |
| } | |
| .game-over, | |
| .level-complete { | |
| position: absolute; | |
| top: 50%; | |
| left: 50%; | |
| transform: translate(-50%, -50%); | |
| color: #ff0000; | |
| font-size: 28px; | |
| font-weight: 900; | |
| text-shadow: 0 0 20px #ff0000; | |
| text-align: center; | |
| display: none; | |
| } | |
| .level-complete { | |
| color: #00ff00; | |
| text-shadow: 0 0 20px #00ff00; | |
| } | |
| .start-screen { | |
| position: absolute; | |
| top: 50%; | |
| left: 50%; | |
| transform: translate(-50%, -50%); | |
| color: #00ffff; | |
| font-size: 20px; | |
| font-weight: bold; | |
| text-shadow: 0 0 20px #00ffff; | |
| text-align: center; | |
| animation: pulse 2s infinite; | |
| } | |
| @keyframes pulse { | |
| 0%, | |
| 100% { | |
| opacity: 1; | |
| } | |
| 50% { | |
| opacity: 0.5; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="arcade-cabinet"> | |
| <div class="title">DX BRICK BREAKER</div> | |
| <div class="screen-bezel"> | |
| <canvas id="gameCanvas" width="520" height="580"></canvas> | |
| <div class="score-display">SCORE: <span id="score">0</span></div> | |
| <div class="lives-display">LIVES: <span id="lives">3</span></div> | |
| <div class="level-display">LEVEL: <span id="level">1</span></div> | |
| <div class="game-over" id="gameOver"> | |
| GAME OVER<br /> | |
| <div style="font-size: 16px; margin-top: 10px"> | |
| PRESS SPACE TO RESTART | |
| </div> | |
| </div> | |
| <div class="level-complete" id="levelComplete"> | |
| LEVEL COMPLETE!<br /> | |
| <div style="font-size: 16px; margin-top: 10px"> | |
| PRESS SPACE FOR NEXT LEVEL | |
| </div> | |
| </div> | |
| <div class="start-screen" id="startScreen"> | |
| PRESS SPACE TO START<br /> | |
| <div style="font-size: 14px; margin-top: 20px"> | |
| LEFT/RIGHT ARROWS TO MOVE PADDLE<br /> | |
| SPACEBAR TO LAUNCH BALL | |
| </div> | |
| </div> | |
| </div> | |
| <div class="controls"> | |
| <div class="joystick"> | |
| <div class="joystick-base"> | |
| <div class="joystick-stick"></div> | |
| </div> | |
| <div style="color: #00ffff; margin-top: 10px; font-size: 12px"> | |
| MOVE | |
| </div> | |
| </div> | |
| <div class="buttons"> | |
| <button class="button launch-button">LAUNCH</button> | |
| <div style="color: #00ffff; margin-top: 10px; font-size: 12px"> | |
| BALL | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| const canvas = document.getElementById("gameCanvas"); | |
| const ctx = canvas.getContext("2d"); | |
| const scoreElement = document.getElementById("score"); | |
| const livesElement = document.getElementById("lives"); | |
| const levelElement = document.getElementById("level"); | |
| const gameOverElement = document.getElementById("gameOver"); | |
| const levelCompleteElement = document.getElementById("levelComplete"); | |
| const startScreenElement = document.getElementById("startScreen"); | |
| // Game state | |
| let gameState = "start"; // 'start', 'playing', 'gameOver', 'levelComplete' | |
| let score = 0; | |
| let lives = 3; | |
| let level = 1; | |
| let ballLaunched = false; | |
| // Paddle object | |
| const paddle = { | |
| x: canvas.width / 2 - 60, | |
| y: canvas.height - 30, | |
| width: 120, | |
| height: 15, | |
| speed: 8, | |
| color: "#00ff00", | |
| }; | |
| // Ball object | |
| const ball = { | |
| x: canvas.width / 2, | |
| y: canvas.height - 50, | |
| radius: 8, | |
| vx: 0, | |
| vy: 0, | |
| speed: 6, | |
| color: "#ffff00", | |
| }; | |
| // Game arrays | |
| let bricks = []; | |
| let particles = []; | |
| let powerUps = []; | |
| // Input handling | |
| const keys = {}; | |
| // Brick colors by row | |
| const brickColors = [ | |
| "#ff0000", | |
| "#ff4400", | |
| "#ff8800", | |
| "#ffcc00", | |
| "#88ff00", | |
| "#00ff00", | |
| "#00ff88", | |
| "#00ffff", | |
| ]; | |
| // Initialize bricks | |
| function initBricks() { | |
| bricks = []; | |
| const rows = 8; | |
| const cols = 10; | |
| const brickWidth = 48; | |
| const brickHeight = 20; | |
| const offsetX = 10; | |
| const offsetY = 100; | |
| for (let row = 0; row < rows; row++) { | |
| for (let col = 0; col < cols; col++) { | |
| bricks.push({ | |
| x: col * (brickWidth + 2) + offsetX, | |
| y: row * (brickHeight + 2) + offsetY, | |
| width: brickWidth, | |
| height: brickHeight, | |
| color: brickColors[row], | |
| hits: 1, | |
| points: (8 - row) * 10, | |
| }); | |
| } | |
| } | |
| } | |
| // Create particle explosion | |
| function createExplosion(x, y, color) { | |
| for (let i = 0; i < 6; i++) { | |
| particles.push({ | |
| x: x, | |
| y: y, | |
| vx: (Math.random() - 0.5) * 6, | |
| vy: (Math.random() - 0.5) * 6, | |
| life: 20, | |
| maxLife: 20, | |
| color: color, | |
| }); | |
| } | |
| } | |
| // Reset ball position | |
| function resetBall() { | |
| ball.x = paddle.x + paddle.width / 2; | |
| ball.y = paddle.y - ball.radius - 5; | |
| ball.vx = 0; | |
| ball.vy = 0; | |
| ballLaunched = false; | |
| } | |
| // Launch ball | |
| function launchBall() { | |
| if (!ballLaunched) { | |
| const angle = ((Math.random() - 0.5) * Math.PI) / 3; // Random angle between -30° and 30° | |
| ball.vx = Math.sin(angle) * ball.speed; | |
| ball.vy = -Math.cos(angle) * ball.speed; | |
| ballLaunched = true; | |
| } | |
| } | |
| // Update game objects | |
| function update() { | |
| if (gameState !== "playing") return; | |
| // Move paddle | |
| if (keys["ArrowLeft"] && paddle.x > 0) { | |
| paddle.x -= paddle.speed; | |
| } | |
| if (keys["ArrowRight"] && paddle.x < canvas.width - paddle.width) { | |
| paddle.x += paddle.speed; | |
| } | |
| // Launch ball | |
| if (keys[" "] && !ballLaunched) { | |
| launchBall(); | |
| } | |
| // Move ball if launched | |
| if (ballLaunched) { | |
| ball.x += ball.vx; | |
| ball.y += ball.vy; | |
| // Ball collision with walls | |
| if ( | |
| ball.x - ball.radius <= 0 || | |
| ball.x + ball.radius >= canvas.width | |
| ) { | |
| ball.vx = -ball.vx; | |
| ball.x = Math.max( | |
| ball.radius, | |
| Math.min(canvas.width - ball.radius, ball.x), | |
| ); | |
| } | |
| if (ball.y - ball.radius <= 0) { | |
| ball.vy = -ball.vy; | |
| ball.y = ball.radius; | |
| } | |
| // Ball collision with paddle | |
| if ( | |
| ball.y + ball.radius >= paddle.y && | |
| ball.x >= paddle.x && | |
| ball.x <= paddle.x + paddle.width && | |
| ball.vy > 0 | |
| ) { | |
| // Calculate bounce angle based on where ball hits paddle | |
| const hitPos = (ball.x - paddle.x) / paddle.width; | |
| const bounceAngle = ((hitPos - 0.5) * Math.PI) / 3; | |
| ball.vx = Math.sin(bounceAngle) * ball.speed; | |
| ball.vy = -Math.abs(Math.cos(bounceAngle) * ball.speed); | |
| ball.y = paddle.y - ball.radius; | |
| } | |
| // Ball collision with bricks | |
| for (let i = bricks.length - 1; i >= 0; i--) { | |
| const brick = bricks[i]; | |
| 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 | |
| ) { | |
| // Determine collision side | |
| 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.vx = -ball.vx; | |
| } else { | |
| ball.vy = -ball.vy; | |
| } | |
| // Create explosion | |
| createExplosion( | |
| brick.x + brick.width / 2, | |
| brick.y + brick.height / 2, | |
| brick.color, | |
| ); | |
| // Increase score | |
| score += brick.points; | |
| scoreElement.textContent = score; | |
| // Remove brick | |
| bricks.splice(i, 1); | |
| break; | |
| } | |
| } | |
| // Ball falls below paddle | |
| if (ball.y > canvas.height) { | |
| lives--; | |
| livesElement.textContent = lives; | |
| if (lives <= 0) { | |
| gameState = "gameOver"; | |
| gameOverElement.style.display = "block"; | |
| } else { | |
| resetBall(); | |
| } | |
| } | |
| } else { | |
| // Ball follows paddle when not launched | |
| ball.x = paddle.x + paddle.width / 2; | |
| } | |
| // Check if all bricks are destroyed | |
| if (bricks.length === 0) { | |
| gameState = "levelComplete"; | |
| levelCompleteElement.style.display = "block"; | |
| } | |
| // Update particles | |
| particles = particles.filter((particle) => { | |
| particle.x += particle.vx; | |
| particle.y += particle.vy; | |
| particle.life--; | |
| particle.vx *= 0.98; | |
| particle.vy *= 0.98; | |
| return particle.life > 0; | |
| }); | |
| } | |
| // Draw game objects | |
| function draw() { | |
| // Clear canvas with gradient background | |
| const gradient = ctx.createLinearGradient(0, 0, 0, canvas.height); | |
| gradient.addColorStop(0, "#000033"); | |
| gradient.addColorStop(1, "#000011"); | |
| ctx.fillStyle = gradient; | |
| ctx.fillRect(0, 0, canvas.width, canvas.height); | |
| if (gameState === "playing" || gameState === "levelComplete") { | |
| // Draw bricks | |
| bricks.forEach((brick) => { | |
| // Main brick | |
| ctx.fillStyle = brick.color; | |
| ctx.fillRect(brick.x, brick.y, brick.width, brick.height); | |
| // Brick highlight | |
| ctx.fillStyle = "rgba(255, 255, 255, 0.3)"; | |
| ctx.fillRect(brick.x, brick.y, brick.width, 3); | |
| ctx.fillRect(brick.x, brick.y, 3, brick.height); | |
| // Brick shadow | |
| ctx.fillStyle = "rgba(0, 0, 0, 0.3)"; | |
| ctx.fillRect(brick.x + brick.width - 3, brick.y, 3, brick.height); | |
| ctx.fillRect(brick.x, brick.y + brick.height - 3, brick.width, 3); | |
| }); | |
| // Draw paddle | |
| const paddleGradient = ctx.createLinearGradient( | |
| 0, | |
| paddle.y, | |
| 0, | |
| paddle.y + paddle.height, | |
| ); | |
| paddleGradient.addColorStop(0, "#00ffff"); | |
| paddleGradient.addColorStop(1, "#00aa88"); | |
| ctx.fillStyle = paddleGradient; | |
| ctx.fillRect(paddle.x, paddle.y, paddle.width, paddle.height); | |
| // Paddle glow | |
| ctx.shadowColor = paddle.color; | |
| ctx.shadowBlur = 10; | |
| ctx.fillRect(paddle.x, paddle.y, paddle.width, paddle.height); | |
| ctx.shadowBlur = 0; | |
| // Draw ball | |
| ctx.beginPath(); | |
| ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2); | |
| ctx.fillStyle = ball.color; | |
| ctx.fill(); | |
| // Ball glow | |
| ctx.shadowColor = ball.color; | |
| ctx.shadowBlur = 15; | |
| ctx.beginPath(); | |
| ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2); | |
| ctx.fill(); | |
| ctx.shadowBlur = 0; | |
| // Ball trail effect | |
| if (ballLaunched) { | |
| ctx.beginPath(); | |
| ctx.arc( | |
| ball.x - ball.vx * 0.5, | |
| ball.y - ball.vy * 0.5, | |
| ball.radius * 0.7, | |
| 0, | |
| Math.PI * 2, | |
| ); | |
| ctx.fillStyle = "rgba(255, 255, 0, 0.3)"; | |
| ctx.fill(); | |
| } | |
| // Draw particles | |
| particles.forEach((particle) => { | |
| const alpha = particle.life / particle.maxLife; | |
| ctx.globalAlpha = alpha; | |
| ctx.fillStyle = particle.color; | |
| ctx.fillRect(particle.x - 2, particle.y - 2, 4, 4); | |
| }); | |
| ctx.globalAlpha = 1; | |
| } | |
| } | |
| // Game loop | |
| function gameLoop() { | |
| update(); | |
| draw(); | |
| requestAnimationFrame(gameLoop); | |
| } | |
| // Start game | |
| function startGame() { | |
| gameState = "playing"; | |
| score = 0; | |
| lives = 3; | |
| level = 1; | |
| particles = []; | |
| initBricks(); | |
| resetBall(); | |
| scoreElement.textContent = score; | |
| livesElement.textContent = lives; | |
| levelElement.textContent = level; | |
| startScreenElement.style.display = "none"; | |
| gameOverElement.style.display = "none"; | |
| levelCompleteElement.style.display = "none"; | |
| } | |
| // Next level | |
| function nextLevel() { | |
| level++; | |
| gameState = "playing"; | |
| particles = []; | |
| // Increase ball speed slightly | |
| ball.speed += 0.5; | |
| initBricks(); | |
| resetBall(); | |
| levelElement.textContent = level; | |
| levelCompleteElement.style.display = "none"; | |
| } | |
| // Reset game | |
| function resetGame() { | |
| gameState = "start"; | |
| ball.speed = 6; // Reset ball speed | |
| startScreenElement.style.display = "block"; | |
| gameOverElement.style.display = "none"; | |
| levelCompleteElement.style.display = "none"; | |
| } | |
| // Event listeners | |
| document.addEventListener("keydown", (e) => { | |
| keys[e.key] = true; | |
| if (e.key === " ") { | |
| e.preventDefault(); | |
| if (gameState === "start") { | |
| startGame(); | |
| } else if (gameState === "gameOver") { | |
| resetGame(); | |
| } else if (gameState === "levelComplete") { | |
| nextLevel(); | |
| } else if (gameState === "playing" && !ballLaunched) { | |
| launchBall(); | |
| } | |
| } | |
| }); | |
| document.addEventListener("keyup", (e) => { | |
| keys[e.key] = false; | |
| }); | |
| // Launch button click | |
| document.querySelector(".launch-button").addEventListener("click", () => { | |
| if (gameState === "playing" && !ballLaunched) { | |
| launchBall(); | |
| } | |
| }); | |
| // Initialize and start | |
| gameLoop(); | |
| </script> | |
| </body> | |
| </html> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment