Kleiner JavaScript Kurs

Spiel "Flappy Bird"

Das Spiel habe ich in Anlehnung an den OpenHPI - Kurs "Spieleentwicklung mit JavaScript: Flappy Bird" entwickelt. Als "Spielfläche verwenden wir ein Canvas - Element (mit Rahmen und Hintergrundfarbe). Die Steuerung erfolgt mit der Tastatur. Ggf. benötigen wir später auch noch einen Button zum Starten des Spiels.

<!DOCTYPE html>
<html lang="de">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Flappy Bird</title>
        <style>
        	canvas {
              border: 1px solid black; 
              background-color: yellow;}
        </style>
    </head>                    
    <body>
		<canvas id="myCanvas" width="480" height="600"></canvas>
    </body>
</html>

Im Script müssen wir als erstes das Canvas für das Zeichnen vorbereiten:

<script>
    const canvas = document.getElementById("myCanvas");
    const ctx = canvas.getContext("2d");
    const breite = canvas.width;
    const hoehe = canvas.height;
    //alert(breite + "  " + hoehe);

Um die Programmierung des Spiels zu vereinfachen, werden wir alle Spiel - Elemente (Vogel / bird, Röhren / pipe) als Objekte programmieren


Der Vogel (bird) als Objekt (mit den Eigenschaften x, y, radius, speed und den Methoden draw() und update():
const bird = {
    x: breite/2,
    y: hoehe/2,
    radius: 20,
    speed: 1,
    draw() {
        // Vogel zeichnen
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
        ctx.stroke();
    },
    update() {
        this.x += this.speed;
        if (bird.y < hoehe-this.radius) {
            bird.y += 1;
        }
    }  
};
// Das Hauptprogramm (game - loop)
bird.draw();
Das Hauptprogramm zum Bewegen des Vogels:
bird.x = 0;
bird.y = 1/4*hoehe;
function loop() {
  //Canvas-Bereich clearen
  ctx.clearRect(0, 0, breite, hoehe);
  // b) Wir stellen sicher dass der Vogel innerhalb des Canvas bleibt.
  if (bird.x > breite) {
    bird.x = 0;
  }
  bird.draw();
  bird.update();	
  window.requestAnimationFrame(loop);
}
window.requestAnimationFrame(loop);

Fliegen mit Tastatursteuerung:
Zunächst richten wir eine Ereignissteuerung ein, die auf einen Tastendruck reagiert. Bei jedem Druck auf eine beliebige Taste soll die Funktion "fly" ausgeführt werden. Achtung: das Programm reagiert nur auf den Tastendruck, wenn vorher auf das Spiel (das "document") geklickt wurde

document.addEventListener("keydown", fly);
function fly(){
  bird.y = bird.y - hoehe/20;
}

Die Röhre (pipe) als Objekt (mit den Eigenschaften x, width, height, speed und den Methoden draw() und update():
// Die Röhre als Objekt (pipe)
    const pipe = {
            x: 350,
            width: 50,
            height: 150,
            speed: -5,
            draw() {
                ctx.fillRect(this.x, 0, this.width, this.height);
            },
            update() {
                this.x += this.speed
            }  
      };
// Das Hauptprogramm (game - loop)
      function loop() {
          ctx.clearRect(0, 0, screenWidth, screenHeight);

          pipe.draw();
          pipe.update();

          window.requestAnimationFrame(loop);
        }

        window.requestAnimationFrame(loop);

Als nächstes wollen wir 3 Röhren von rechts nach links bewegen.Dazu schreiben wir (mit einer for - Schleife) 3 pipe - Objekte in ein pipes Array.

const canvas = document.getElementById('canvas');
            const ctx = canvas.getContext('2d');
            const screenWidth = canvas.clientWidth;
            const screenHeight = canvas.clientHeight; 
      		
            const pipes = [];
            const pipeCount = 3; 
            for(let i=0; i < pipeCount; i++){
              pipes.push({	x: screenWidth + i * screenWidth / pipeCount,
                            width: 50,
                            height: 150,
                            speed: -5,
                            draw() {
                                ctx.fillRect(this.x, 0, this.width, this.height);
                            },
                            update() {
                                this.x += this.speed
                            }  
                      });
            }  
           
          function loop() {
              ctx.clearRect(0, 0, screenWidth, screenHeight);

              for (let i = 0; i < pipeCount; i++) {
              pipes[i].draw();
              pipes[i].update();
            	}

              window.requestAnimationFrame(loop);
            }

            window.requestAnimationFrame(loop);

Beschreibung wird fortgesetzt