Lernfabrik

🎮 JavaScript Spiel programmieren

In dieser Anleitung lernst du Schritt für Schritt, wie du ein eigenes Spiel in JavaScript programmierst. Du baust den "Luftballonregen" – ein Spiel, bei dem du Ballons fangen musst, während du Fallen ausweichst.

📝 Was du brauchst:
✅ Einen Texteditor (z.B. Notepad, VS Code, oder direkt hier im Browser)
✅ Einen Webbrowser (Chrome, Firefox, Safari)
✅ Etwas Geduld und Spaß am Programmieren!

🎯 Das fertige Spiel – zum Ausprobieren!

Bevor du loslegst, kannst du hier das Endergebnis testen:

🎈 LUFTBALLONREGEN Demo

A ← Links D → Rechts SPACE Start / Neustart ESC Pause
💡 Klicke auf das Pause-Symbol ⏸ oben rechts im Spiel

📚 Schritt-für-Schritt Anleitung

Kopiere den Code aus jedem Schritt in deine Datei und teste ihn!

1

HTML-Grundgerüst erstellen

Erstelle eine neue Datei mit dem Namen spiel.html auf deinem Desktop. Füge dieses Grundgerüst ein:

<!DOCTYPE html> <html> <head> <title>Mein erstes Spiel</title> <style> body { margin: 0; display: flex; justify-content: center; align-items: center; height: 100vh; background: #1a1a2e; } canvas { border: 3px solid white; border-radius: 10px; } </style> </head> <body> <canvas id="spiel" width="800" height="700"></canvas> <script> // Hier kommt später der JavaScript-Code rein console.log("Hallo Welt!"); </script> </body> </html>
✅ Teste es! Öffne die Datei im Browser. Du solltest ein leeres, dunkles Fenster sehen. In der Browser-Konsole (F12 → Console) siehst du "Hallo Welt!".
2

Canvas und Farben vorbereiten

Jetzt bereiten wir die Spielumgebung vor. Ersetze den Inhalt von <script> mit diesem Code:

// ====== 1. Canvas holen ====== const canvas = document.getElementById('spiel'); const ctx = canvas.getContext('2d'); // ====== 2. Farben definieren ====== const FARBEN = { WEISS: '#FFFFFF', BLAU: '#87CEEB', GRUEN: '#228B22', ROT: '#FF0000', GELB: '#FFFF00', GRAU: '#808080' }; // ====== 3. Ersten Test zeichnen ====== ctx.fillStyle = FARBEN.BLAU; ctx.fillRect(0, 0, 800, 700); ctx.fillStyle = FARBEN.ROT; ctx.fillRect(375, 550, 50, 50);
✅ Teste es! Jetzt siehst du einen blauen Hintergrund mit einem roten Quadrat.
💡 Erklärung: canvas ist die Leinwand, auf der wir zeichnen. ctx ist der Stift, mit dem wir malen. Farben speichern wir in einem Objekt.
3

Spieler bewegen mit Tastatur

Jetzt machen wir den roten Block beweglich! Füge diesen Code hinzu:

// ====== 4. Spieler-Variablen ====== let spieler = { x: 375, y: 550, breite: 50, hoehe: 50, geschw: 8 }; // ====== 5. Tastatur-Speicher ====== let tasten = {}; document.addEventListener('keydown', (e) => { tasten[e.key] = true; }); document.addEventListener('keyup', (e) => { tasten[e.key] = false; }); // ====== 6. Spiel-Schleife ====== function gameLoop() { // Hintergrund löschen ctx.fillStyle = FARBEN.BLAU; ctx.fillRect(0, 0, 800, 700); // Spieler bewegen if (tasten['a'] || tasten['A']) { spieler.x -= spieler.geschw; } if (tasten['d'] || tasten['D']) { spieler.x += spieler.geschw; } // Spieler am Rand stoppen if (spieler.x < 0) spieler.x = 0; if (spieler.x > 800 - spieler.breite) spieler.x = 800 - spieler.breite; // Spieler zeichnen ctx.fillStyle = FARBEN.ROT; ctx.fillRect(spieler.x, spieler.y, spieler.breite, spieler.hoehe); // Nächstes Bild requestAnimationFrame(gameLoop); } // Spiel starten gameLoop();
✅ Teste es! Jetzt kannst du den roten Block mit A und D bewegen!
💡 Erklärung: requestAnimationFrame sorgt dafür, dass das Spiel immer wieder neu gezeichnet wird (wie ein Zeichentrickfilm). Die Tastatur-Events speichern, welche Tasten gerade gedrückt sind.
4

Ballons erstellen (die Punkte)

Jetzt kommen die Ballons! Füge diesen Code oberhalb von gameLoop() ein:

// ====== 7. Ballon-Klasse ====== class Ballon { constructor() { this.x = Math.random() * 700 + 50; this.y = Math.random() * -200 - 50; this.radius = Math.random() * 15 + 20; this.farbe = [FARBEN.ROT, FARBEN.GELB][Math.floor(Math.random() * 2)]; this.geschw = 1; this.aktiv = true; } bewegen() { this.y += this.geschw; } zeichnen() { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2); ctx.fillStyle = this.farbe; ctx.fill(); ctx.strokeStyle = FARBEN.SCHWARZ; ctx.lineWidth = 2; ctx.stroke(); } kollision() { return (this.x - this.radius < spieler.x + spieler.breite && this.x + this.radius > spieler.x && this.y - this.radius < spieler.y + spieler.hoehe && this.y + this.radius > spieler.y); } } // ====== 8. Ballons erstellen ====== let ballons = []; let punkte = 0; for (let i = 0; i < 2; i++) { ballons.push(new Ballon()); }

Füge dann in gameLoop() nach dem Spieler-Code ein:

// Ballons bewegen und zeichnen for (let b of ballons) { if (b.aktiv) { b.bewegen(); b.zeichnen(); // Ballon gefangen? if (b.kollision()) { punkte++; b.aktiv = false; ballons.push(new Ballon()); } // Ballon verpasst? if (b.y > 750) { b.aktiv = false; ballons.push(new Ballon()); } } } // Kaputte Ballons löschen ballons = ballons.filter(b => b.aktiv); // Punkte anzeigen ctx.fillStyle = FARBEN.WEISS; ctx.font = '30px Arial'; ctx.fillText('Punkte: ' + punkte, 20, 45);
✅ Teste es! Jetzt fallen Ballons vom Himmel! Fange sie mit deinem roten Block. Oben links siehst du deine Punktzahl.
5

Leben und Fallen (Quadrate)

Jetzt kommen die Quadrate (Fallen) und deine Leben! Füge diesen Code ein:

// ====== 9. Quadrat-Klasse (Fallen) ====== class Quadrat { constructor() { this.x = Math.random() * 700 + 50; this.y = Math.random() * -200 - 50; this.groesse = Math.random() * 15 + 25; this.geschw = 1; this.aktiv = true; } bewegen() { this.y += this.geschw; } zeichnen() { ctx.fillStyle = FARBEN.GRAU; ctx.fillRect(this.x, this.y, this.groesse, this.groesse); ctx.strokeStyle = FARBEN.SCHWARZ; ctx.lineWidth = 2; ctx.strokeRect(this.x, this.y, this.groesse, this.groesse); } kollision() { return (this.x < spieler.x + spieler.breite && this.x + this.groesse > spieler.x && this.y < spieler.y + spieler.hoehe && this.y + this.groesse > spieler.y); } } // ====== 10. Leben und Quadrate ====== let leben = 3; let quadrate = []; for (let i = 0; i < 1; i++) { quadrate.push(new Quadrat()); }

Füge dann in gameLoop() nach den Ballons ein:

// Quadrate bewegen und prüfen for (let q of quadrate) { if (q.aktiv) { q.bewegen(); q.zeichnen(); // Quadrat gefangen? (FALLE!) if (q.kollision()) { leben--; punkte -= 5; q.aktiv = false; quadrate.push(new Quadrat()); if (leben <= 0) { alert('💀 Game Over! Punkte: ' + punkte); location.reload(); } } // Quadrat sicher vorbei if (q.y > 750) { q.aktiv = false; quadrate.push(new Quadrat()); } } } quadrate = quadrate.filter(q => q.aktiv); // Leben anzeigen (Herzen) let lebenText = ''; for (let i = 0; i < leben; i++) { lebenText += '❤️ '; } ctx.fillStyle = FARBEN.WEISS; ctx.font = '30px Arial'; ctx.textAlign = 'right'; ctx.fillText(lebenText, 800 - 20, 45); ctx.textAlign = 'left';
✅ Teste es! Jetzt fallen graue Quadrate! Fange sie NICHT – sonst verlierst du ein Leben und 5 Punkte!
6

Startbildschirm und Game Over

Jetzt machen wir es schön mit Startbildschirm und Game Over:

// ====== 11. Spielzustände ====== let startbildschirm = true; let gameover = false; let spielAktiv = true; // ====== 12. Startbildschirm zeichnen ====== function startbildschirmZeichnen() { ctx.fillStyle = FARBEN.BLAU; ctx.fillRect(0, 0, 800, 700); ctx.fillStyle = FARBEN.ROT; ctx.font = 'bold 60px Arial'; ctx.textAlign = 'center'; ctx.fillText('🎈 LUFTBALLONREGEN', 400, 100); ctx.fillStyle = FARBEN.WEISS; ctx.font = '28px Arial'; const texte = [ '📖 REGELN:', 'Fange die Ballons (A und D)', '🟦 Quadrate sind Fallen!', '❤️ Du hast 3 Leben', '', 'Drücke SPACE zum Starten' ]; let y = 160; texte.forEach(t => { ctx.fillText(t, 400, y); y += 40; }); } // ====== 13. SPACE-Taste für Start ====== document.addEventListener('keydown', (e) => { tasten[e.key] = true; if (e.key === ' ' || e.key === 'Space') { e.preventDefault(); if (startbildschirm) { startbildschirm = false; } if (gameover) { location.reload(); } } });

Ändere den Anfang von gameLoop():

function gameLoop() { // Startbildschirm anzeigen if (startbildschirm) { startbildschirmZeichnen(); requestAnimationFrame(gameLoop); return; } // Game Over prüfen if (gameover || !spielAktiv) { ctx.fillStyle = 'rgba(0,0,0,0.8)'; ctx.fillRect(0, 0, 800, 700); ctx.fillStyle = FARBEN.ROT; ctx.font = 'bold 70px Arial'; ctx.textAlign = 'center'; ctx.fillText('💀 GAME OVER', 400, 250); ctx.fillStyle = FARBEN.WEISS; ctx.font = '40px Arial'; ctx.fillText('Punkte: ' + punkte, 400, 340); ctx.font = '28px Arial'; ctx.fillText('SPACE = Neustart', 400, 430); requestAnimationFrame(gameLoop); return; } // ... Rest vom Spiel ... }
✅ Teste es! Jetzt siehst du einen Startbildschirm. Drücke SPACE zum Starten! Bei Game Over kannst du mit SPACE neu starten.
7

Pause und Schwierigkeit

Zum Schluss noch Pause-Funktion und steigende Schwierigkeit:

// ====== 14. Pause ====== let pause = false; document.addEventListener('keydown', (e) => { // ... vorhandene Tasten ... if (e.key === 'Escape') { if (!startbildschirm && !gameover) { pause = !pause; } } }); // In gameLoop() nach dem Startbildschirm-Code: if (pause) { ctx.fillStyle = 'rgba(0,0,0,0.7)'; ctx.fillRect(0, 0, 800, 700); ctx.fillStyle = FARBEN.WEISS; ctx.font = 'bold 60px Arial'; ctx.textAlign = 'center'; ctx.fillText('⏸ PAUSE', 400, 300); ctx.font = '30px Arial'; ctx.fillText('SPACE = Fortsetzen', 400, 400); requestAnimationFrame(gameLoop); return; } // ====== 15. Schwierigkeit steigt ====== let zeit = 0; // In gameLoop() nach dem Spieler-Code: zeit++; if (zeit % 300 === 0) { // Alle 5 Sekunden mehr Ballons if (ballons.length < 5) { ballons.push(new Ballon()); } }
✅ Teste es! Drücke ESC zum Pausieren. Das Spiel wird nach einiger Zeit schwerer!

📋 Kompletter Code zum Kopieren

Hier ist der ganze Code auf einmal – perfekt zum Reinkopieren!

<!DOCTYPE html> <html> <head> <title>Luftballonregen</title> <style> body { margin: 0; display: flex; justify-content: center; align-items: center; height: 100vh; background: #1a1a2e; } canvas { border: 3px solid white; border-radius: 10px; } </style> </head> <body> <canvas id="spiel" width="800" height="700"></canvas> <script> // ============================================================ // 1. CANVAS // ============================================================ const canvas = document.getElementById('spiel'); const ctx = canvas.getContext('2d'); // ============================================================ // 2. FARBEN // ============================================================ const FARBEN = { WEISS: '#FFFFFF', SCHWARZ: '#000000', BLAU: '#87CEEB', GRUEN: '#228B22', ROT: '#FF0000', GELB: '#FFFF00', GRAU: '#808080' }; // ============================================================ // 3. SPIELER // ============================================================ let spieler = { x: 375, y: 550, breite: 50, hoehe: 50, geschw: 8 }; // ============================================================ // 4. SPIELVARIABLEN // ============================================================ let punkte = 0; let leben = 3; let startbildschirm = true; let gameover = false; let pause = false; let zeit = 0; let tasten = {}; let ballons = []; let quadrate = []; // ============================================================ // 5. BALLON-KLASSE // ============================================================ class Ballon { constructor() { this.x = Math.random() * 700 + 50; this.y = Math.random() * -200 - 50; this.radius = Math.random() * 15 + 20; this.farbe = [FARBEN.ROT, FARBEN.GELB][Math.floor(Math.random() * 2)]; this.geschw = 1 + Math.random(); this.aktiv = true; } bewegen() { this.y += this.geschw; } zeichnen() { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2); ctx.fillStyle = this.farbe; ctx.fill(); ctx.strokeStyle = FARBEN.SCHWARZ; ctx.lineWidth = 2; ctx.stroke(); } kollision() { return (this.x - this.radius < spieler.x + spieler.breite && this.x + this.radius > spieler.x && this.y - this.radius < spieler.y + spieler.hoehe && this.y + this.radius > spieler.y); } } // ============================================================ // 6. QUADRAT-KLASSE (FALLEN) // ============================================================ class Quadrat { constructor() { this.x = Math.random() * 700 + 50; this.y = Math.random() * -200 - 50; this.groesse = Math.random() * 15 + 25; this.geschw = 1 + Math.random(); this.aktiv = true; } bewegen() { this.y += this.geschw; } zeichnen() { ctx.fillStyle = FARBEN.GRAU; ctx.fillRect(this.x, this.y, this.groesse, this.groesse); ctx.strokeStyle = FARBEN.SCHWARZ; ctx.lineWidth = 2; ctx.strokeRect(this.x, this.y, this.groesse, this.groesse); } kollision() { return (this.x < spieler.x + spieler.breite && this.x + this.groesse > spieler.x && this.y < spieler.y + spieler.hoehe && this.y + this.groesse > spieler.y); } } // ============================================================ // 7. OBJEKTE ERSTELLEN // ============================================================ for (let i = 0; i < 2; i++) ballons.push(new Ballon()); quadrate.push(new Quadrat()); // ============================================================ // 8. STARTBILDSCHIRM // ============================================================ function startbildschirmZeichnen() { ctx.fillStyle = FARBEN.BLAU; ctx.fillRect(0, 0, 800, 700); ctx.fillStyle = FARBEN.ROT; ctx.font = 'bold 60px Arial'; ctx.textAlign = 'center'; ctx.fillText('🎈 LUFTBALLONREGEN', 400, 100); ctx.fillStyle = FARBEN.WEISS; ctx.font = '28px Arial'; const texte = [ '📖 REGELN:', 'Fange die Ballons (A und D)', '🟦 Quadrate sind Fallen!', '❤️ Du hast 3 Leben', '', 'Drücke SPACE zum Starten' ]; let y = 160; texte.forEach(t => { ctx.fillText(t, 400, y); y += 40; }); } // ============================================================ // 9. TASTATUR // ============================================================ document.addEventListener('keydown', (e) => { tasten[e.key] = true; if (e.key === ' ' || e.key === 'Space') { e.preventDefault(); if (startbildschirm) startbildschirm = false; if (gameover) location.reload(); if (pause) pause = false; } if (e.key === 'Escape') { if (!startbildschirm && !gameover) pause = !pause; } }); document.addEventListener('keyup', (e) => { tasten[e.key] = false; }); // ============================================================ // 10. HAUPTSPIELSCHLEIFE // ============================================================ function gameLoop() { // STARTBILDSCHIRM if (startbildschirm) { startbildschirmZeichnen(); requestAnimationFrame(gameLoop); return; } // PAUSE if (pause) { ctx.fillStyle = 'rgba(0,0,0,0.7)'; ctx.fillRect(0, 0, 800, 700); ctx.fillStyle = FARBEN.WEISS; ctx.font = 'bold 60px Arial'; ctx.textAlign = 'center'; ctx.fillText('⏸ PAUSE', 400, 300); ctx.font = '30px Arial'; ctx.fillText('SPACE = Fortsetzen', 400, 400); requestAnimationFrame(gameLoop); return; } // GAME OVER if (gameover) { ctx.fillStyle = 'rgba(0,0,0,0.8)'; ctx.fillRect(0, 0, 800, 700); ctx.fillStyle = FARBEN.ROT; ctx.font = 'bold 70px Arial'; ctx.textAlign = 'center'; ctx.fillText('💀 GAME OVER', 400, 250); ctx.fillStyle = FARBEN.WEISS; ctx.font = '40px Arial'; ctx.fillText('Punkte: ' + punkte, 400, 340); ctx.font = '28px Arial'; ctx.fillText('SPACE = Neustart', 400, 430); requestAnimationFrame(gameLoop); return; } // ----- HINTERGRUND ----- ctx.fillStyle = FARBEN.BLAU; ctx.fillRect(0, 0, 800, 700); ctx.fillStyle = FARBEN.GRUEN; ctx.fillRect(0, 600, 800, 100); // ----- SPIELER BEWEGEN ----- if (tasten['a'] || tasten['A']) spieler.x -= spieler.geschw; if (tasten['d'] || tasten['D']) spieler.x += spieler.geschw; if (spieler.x < 0) spieler.x = 0; if (spieler.x > 800 - spieler.breite) spieler.x = 800 - spieler.breite; ctx.fillStyle = FARBEN.ROT; ctx.fillRect(spieler.x, spieler.y, spieler.breite, spieler.hoehe); // ----- SCHWIERIGKEIT ----- zeit++; if (zeit % 300 === 0 && ballons.length < 5) { ballons.push(new Ballon()); } // ----- BALLONS ----- for (let b of ballons) { if (b.aktiv) { b.bewegen(); b.zeichnen(); if (b.kollision()) { punkte++; b.aktiv = false; ballons.push(new Ballon()); } if (b.y > 750) { b.aktiv = false; ballons.push(new Ballon()); } } } ballons = ballons.filter(b => b.aktiv); // ----- QUADRATE (FALLEN) ----- for (let q of quadrate) { if (q.aktiv) { q.bewegen(); q.zeichnen(); if (q.kollision()) { leben--; punkte -= 5; q.aktiv = false; quadrate.push(new Quadrat()); if (leben <= 0) gameover = true; } if (q.y > 750) { q.aktiv = false; quadrate.push(new Quadrat()); } } } quadrate = quadrate.filter(q => q.aktiv); // ----- UI ----- ctx.fillStyle = FARBEN.WEISS; ctx.font = '30px Arial'; ctx.textAlign = 'left'; ctx.fillText('Punkte: ' + punkte, 20, 45); let lebenText = ''; for (let i = 0; i < leben; i++) lebenText += '❤️ '; ctx.textAlign = 'right'; ctx.fillText(lebenText, 800 - 20, 45); // Pause-Button ctx.strokeStyle = FARBEN.WEISS; ctx.lineWidth = 2; ctx.strokeRect(800 - 60, 10, 40, 40); ctx.fillStyle = FARBEN.WEISS; ctx.fillRect(800 - 50, 20, 8, 20); ctx.fillRect(800 - 30, 20, 8, 20); requestAnimationFrame(gameLoop); } // ============================================================ // 11. SPIEL STARTEN // ============================================================ gameLoop(); // Pause-Button mit Maus canvas.addEventListener('click', (e) => { const rect = canvas.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; if (x > 800 - 60 && x < 800 - 20 && y > 10 && y < 50) { if (!startbildschirm && !gameover) pause = !pause; } }); console.log('🎮 Spiel geladen! Drücke SPACE zum Starten.'); console.log('Steuerung: A = Links, D = Rechts'); </script> </body> </html>
🎯 JETZT BIST DU DRAN!
1. Kopiere den kompletten Code in eine neue Datei.
2. Speichere sie als mein_spiel.html auf dem Desktop.
3. Öffne die Datei im Browser.
4. Drücke SPACE und spiele!

💡 Tipp: Du kannst den Code ändern und eigene Ideen einbauen!

🎨 Ideen zum Weiterbauen

🔴 Neue Farben

Ändere die Farben der Ballons oder des Spielers!

FARBEN.ROT = '#FF1493'
⚡ Power-Ups

Füge goldene Ballons hinzu, die 5 Punkte geben!

if (b.farbe === GOLD) punkte += 5
🎵 Sound

Füge Soundeffekte beim Fangen oder Verlieren hinzu!

new Audio('sound.mp3').play()

🎉 GLÜCKWUNSCH!
Du hast dein erstes JavaScript-Spiel programmiert!
Du kannst es jetzt deinen Freunden zeigen oder weiter verbessern.
🔄 Spiel neu laden