Sandbox zum Testen
-
-
Wie schaut das mit längeren Codes aus (viel Spaß beim Zocken übrigens)
HTML
Alles anzeigen<!DOCTYPE html> <html lang="de"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>HTML5 Breakout - Deluxe</title> <style> body { background: #111; color: #fff; font-family: sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; margin: 0; } canvas { background: #000; border: 3px solid #333; box-shadow: 0 0 20px rgba(255, 255, 255, 0.1); } .info { margin-top: 10px; color: #aaa; font-size: 14px; } </style> </head> <body> <canvas id="gameCanvas" width="600" height="400"></canvas> <div class="info">Steuerung: Pfeiltasten (Links/Rechts) oder Maus | Klick zum Starten/Audio aktivieren</div> <script> const canvas = document.getElementById("gameCanvas"); const ctx = canvas.getContext("2d"); // Audio-Kontext (Web Audio API) let audioCtx = null; function initAudio() { if (!audioCtx) { audioCtx = new (window.AudioContext || window.webkitAudioContext)(); } if (audioCtx.state === 'suspended') { audioCtx.resume(); } } function playSound(type) { if (!audioCtx) return; const osc = audioCtx.createOscillator(); const gain = audioCtx.createGain(); osc.connect(gain); gain.connect(audioCtx.destination); const now = audioCtx.currentTime; if (type === 'bounce') { osc.frequency.setValueAtTime(300, now); osc.frequency.exponentialRampToValueAtTime(150, now + 0.05); gain.gain.setValueAtTime(0.2, now); gain.gain.exponentialRampToValueAtTime(0.01, now + 0.05); osc.start(now); osc.stop(now + 0.05); } else if (type === 'brick') { osc.frequency.setValueAtTime(500, now); osc.frequency.exponentialRampToValueAtTime(800, now + 0.08); gain.gain.setValueAtTime(0.25, now); gain.gain.exponentialRampToValueAtTime(0.01, now + 0.08); osc.start(now); osc.stop(now + 0.08); } else if (type === 'powerup') { osc.frequency.setValueAtTime(400, now); osc.frequency.setValueAtTime(600, now + 0.05); osc.frequency.setValueAtTime(800, now + 0.1); gain.gain.setValueAtTime(0.3, now); gain.gain.exponentialRampToValueAtTime(0.01, now + 0.15); osc.start(now); osc.stop(now + 0.15); } else if (type === 'lose') { osc.type = 'sawtooth'; osc.frequency.setValueAtTime(200, now); osc.frequency.exponentialRampToValueAtTime(60, now + 0.3); gain.gain.setValueAtTime(0.3, now); gain.gain.exponentialRampToValueAtTime(0.01, now + 0.3); osc.start(now); osc.stop(now + 0.3); } } // Spielzustand let score = 0; let lives = 3; let gameOver = false; let gameWon = false; // Schläger-Eigenschaften const defaultPaddleWidth = 90; let paddleWidth = defaultPaddleWidth; const paddleHeight = 12; let paddleX = (canvas.width - paddleWidth) / 2; let paddleTimer = null; // Bälle (Array für Multiball-Unterstützung) const ballRadius = 7; let balls = [{ x: canvas.width / 2, y: canvas.height - 30, dx: 3, dy: -3 }]; // Power-ups Array & Typen let powerUps = []; const POWERUP_TYPES = [ { type: 'expand', color: '#2ECC71', label: '+P' }, // Breiterer Schläger { type: 'multiball', color: '#3498DB', label: '3x' }, // 3 Bälle { type: 'life', color: '#E74C3C', label: '+1' } // Extra Leben ]; // Steuerung let rightPressed = false; let leftPressed = false; // Ziegel-Setup const brickRowCount = 5; const brickColumnCount = 8; const brickWidth = 60; const brickHeight = 16; const brickPadding = 10; const brickOffsetTop = 40; const brickOffsetLeft = 20; const brickColors = ["#E74C3C", "#E67E22", "#F1C40F", "#2ECC71", "#3498DB"]; let bricks = []; for (let c = 0; c < brickColumnCount; c++) { bricks[c] = []; for (let r = 0; r < brickRowCount; r++) { bricks[c][r] = { x: 0, y: 0, status: 1 }; } } // Event Listener document.addEventListener("keydown", keyDownHandler, false); document.addEventListener("keyup", keyUpHandler, false); document.addEventListener("mousemove", mouseMoveHandler, false); document.addEventListener("click", initAudio, false); function keyDownHandler(e) { initAudio(); if (e.key === "Right" || e.key === "ArrowRight") rightPressed = true; else if (e.key === "Left" || e.key === "ArrowLeft") leftPressed = true; } function keyUpHandler(e) { if (e.key === "Right" || e.key === "ArrowRight") rightPressed = false; else if (e.key === "Left" || e.key === "ArrowLeft") leftPressed = false; } function mouseMoveHandler(e) { const relativeX = e.clientX - canvas.offsetLeft; if (relativeX > 0 && relativeX < canvas.width) { paddleX = relativeX - paddleWidth / 2; } } // Power-up erzeugen function spawnPowerUp(x, y) { if (Math.random() < 0.3) { // 30% Chance auf Power-up const pType = POWERUP_TYPES[Math.floor(Math.random() * POWERUP_TYPES.length)]; powerUps.push({ x: x + brickWidth / 2, y: y + brickHeight, dy: 2, radius: 10, ...pType }); } } // Power-up anwenden function applyPowerUp(type) { playSound('powerup'); if (type === 'expand') { paddleWidth = 140; clearTimeout(paddleTimer); paddleTimer = setTimeout(() => { paddleWidth = defaultPaddleWidth; }, 8000); } else if (type === 'multiball') { const baseBall = balls[0] || { x: paddleX + paddleWidth / 2, y: canvas.height - 30, dx: 3, dy: -3 }; balls.push( { x: baseBall.x, y: baseBall.y, dx: -3, dy: -3 }, { x: baseBall.x, y: baseBall.y, dx: 1.5, dy: -4 } ); } else if (type === 'life') { lives++; } } // Kollisionserkennung für Ziegel function collisionDetection() { let activeBricks = 0; for (let c = 0; c < brickColumnCount; c++) { for (let r = 0; r < brickRowCount; r++) { const b = bricks[c][r]; if (b.status === 1) { activeBricks++; balls.forEach(ball => { if ( ball.x > b.x && ball.x < b.x + brickWidth && ball.y > b.y && ball.y < b.y + brickHeight ) { ball.dy = -ball.dy; b.status = 0; score += 10; playSound('brick'); spawnPowerUp(b.x, b.y); if (activeBricks - 1 === 0) { gameWon = true; } } }); } } } } // Power-ups aktualisieren und zeichnen function updatePowerUps() { for (let i = powerUps.length - 1; i >= 0; i--) { const p = powerUps[i]; p.y += p.dy; // Zeichnen ctx.beginPath(); ctx.arc(p.x, p.y, p.radius, 0, Math.PI * 2); ctx.fillStyle = p.color; ctx.fill(); ctx.fillStyle = "#FFF"; ctx.font = "bold 10px sans-serif"; ctx.textAlign = "center"; ctx.fillText(p.label, p.x, p.y + 3); ctx.closePath(); // Einsammeln durch Schläger if ( p.y + p.radius >= canvas.height - paddleHeight - 10 && p.x >= paddleX && p.x <= paddleX + paddleWidth ) { applyPowerUp(p.type); powerUps.splice(i, 1); } else if (p.y > canvas.height) { powerUps.splice(i, 1); } } } function drawBricks() { for (let c = 0; c < brickColumnCount; c++) { for (let r = 0; r < brickRowCount; r++) { if (bricks[c][r].status === 1) { const brickX = c * (brickWidth + brickPadding) + brickOffsetLeft; const brickY = r * (brickHeight + brickPadding) + brickOffsetTop; bricks[c][r].x = brickX; bricks[c][r].y = brickY; ctx.beginPath(); ctx.rect(brickX, brickY, brickWidth, brickHeight); ctx.fillStyle = brickColors[r % brickColors.length]; ctx.fill(); ctx.closePath(); } } } } function drawBalls() { balls.forEach(ball => { ctx.beginPath(); ctx.arc(ball.x, ball.y, ballRadius, 0, Math.PI * 2); ctx.fillStyle = "#FFFFFF"; ctx.fill(); ctx.closePath(); }); } function drawPaddle() { ctx.beginPath(); ctx.rect(paddleX, canvas.height - paddleHeight - 10, paddleWidth, paddleHeight); ctx.fillStyle = paddleWidth > defaultPaddleWidth ? "#2ECC71" : "#3498DB"; ctx.fill(); ctx.closePath(); } function drawHUD() { ctx.font = "14px sans-serif"; ctx.fillStyle = "#FFF"; ctx.textAlign = "left"; ctx.fillText(`Punkte: ${score}`, 15, 25); ctx.textAlign = "right"; ctx.fillText(`Leben: ${lives}`, canvas.width - 15, 25); } function drawMessage(text, subtext) { ctx.fillStyle = "rgba(0, 0, 0, 0.75)"; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.font = "28px sans-serif"; ctx.fillStyle = "#FFF"; ctx.textAlign = "center"; ctx.fillText(text, canvas.width / 2, canvas.height / 2 - 10); ctx.font = "16px sans-serif"; ctx.fillStyle = "#AAA"; ctx.fillText(subtext, canvas.width / 2, canvas.height / 2 + 25); } // Hauptschleife function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); drawBricks(); drawBalls(); drawPaddle(); updatePowerUps(); drawHUD(); collisionDetection(); if (gameWon) { drawMessage("GEWONNEN!", "Seite neu laden zum erneuten Spielen"); return; } if (gameOver) { drawMessage("GAME OVER", "Seite neu laden zum erneuten Spielen"); return; } // Ball-Bewegung und Kollisionen for (let i = balls.length - 1; i >= 0; i--) { const ball = balls[i]; // Seitenwände if (ball.x + ball.dx > canvas.width - ballRadius || ball.x + ball.dx < ballRadius) { ball.dx = -ball.dx; playSound('bounce'); } // Decke if (ball.y + ball.dy < ballRadius) { ball.dy = -ball.dy; playSound('bounce'); } else if (ball.y + ball.dy > canvas.height - ballRadius - 10) { // Schläger if (ball.x > paddleX && ball.x < paddleX + paddleWidth) { let hitPoint = (ball.x - (paddleX + paddleWidth / 2)) / (paddleWidth / 2); ball.dx = hitPoint * 4; ball.dy = -Math.abs(ball.dy); playSound('bounce'); } else if (ball.y + ball.dy > canvas.height - ballRadius) { // Ball im Aus balls.splice(i, 1); if (balls.length === 0) { lives--; playSound('lose'); if (!lives) { gameOver = true; } else { // Einzelnen Ball zurücksetzen balls.push({ x: canvas.width / 2, y: canvas.height - 30, dx: 3, dy: -3 }); paddleX = (canvas.width - paddleWidth) / 2; } } } } ball.x += ball.dx; ball.y += ball.dy; } // Schlägerbewegung if (rightPressed && paddleX < canvas.width - paddleWidth) { paddleX += 6; } else if (leftPressed && paddleX > 0) { paddleX -= 6; } requestAnimationFrame(draw); } draw(); </script> </body> </html> -
25. August 2026 um 00:26 KI-generiert
Bei 400 Zeilen scheint der Beitrag ja nicht direkt in die Knie zu gehen – schon mal beruhigend. Die automatische Spracherkennung beim kurzen Beispiel hat bei mir bisher meistens funktioniert, bei längeren oder gemischten Codeblöcken wäre ich aber neugierig, ob sie irgendwann ins Raten kommt.
Praktisch fände ich noch eine Möglichkeit, längere Blöcke einzuklappen oder zumindest Zeilennummern einzublenden. Beim Scrollen durch viel Code verliert man sich sonst ziemlich schnell, wie beim Suchen nach einer fehlenden Klammer um drei Uhr nachts.
Ich hab in solchen Testthreads früher auch gern mal absichtlich kaputten Code eingefügt, um zu sehen, ob das Forum sauber bleibt. Werden eigentlich sehr lange Beiträge begrenzt oder einfach vollständig dargestellt?
Jetzt mitmachen!
Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!