VUE implementiert einen Beispielcode für das Spiel Flappy Bird

VUE implementiert einen Beispielcode für das Spiel Flappy Bird

Flappy Bird ist ein sehr einfaches kleines Spiel, das jeder auf der App gespielt hat. Hier verwenden wir VUE, um eine einfache PC-Version von Flappy Bird zur Unterhaltung zu implementieren~~~~~

Um dieses Spiel zu realisieren, analysieren wir zunächst, welche Teile der Spieloberfläche animiert werden müssen:

1. Der erste ist natürlich der Vogel, der sich auf und ab bewegt;

2. Ein horizontal bewegtes Hintergrundbild lässt den Vogel horizontal fliegen;

3. Reihen von Rohren, die von der rechten Seite des Bildschirms hereinkommen.

Das ist ganz klar. Wir lassen die drei oben genannten Teile gemäß den Regeln laufen und fügen dann die Beurteilung der Regelgrenzen und die Wertung hinzu, und schon erhalten wir ein vollständiges Spiel. Lösen wir es also Stück für Stück.

Definieren wir zunächst einige Konstanten und Variablen:

let rafId = null; // requestAnimationFrame-ID
lass startSpeed ​​​​= 1;
const SPEED = 0.04; // Beschleunigung const UP = 5.0; // Obergrenze der Geschwindigkeitsakkumulation const UP_SUM = 30; // Höhe eines Sprungs const BIRD_WIDTH = 50; // Breite des Vogelbildes 50px
const PIPE_DISTANCE = 350; // Horizontaler Abstand zwischen Rohren let id = 0; // Eindeutige ID des Rohrs, die Zählung beginnt bei 0 ...
 
Daten() {
    zurückkehren {
      Start: falsch,
      Clientbreite: 0,
      Clienthöhe: 0,
      spaceHeight: [240, 200, 160], // Der Abstand zwischen dem oberen und dem unteren RohrpipeArr: [], // Rohr-Arrayscore: 0, // PunktzahljumpSum: 0, // Aktuelle relative SprunghöhejumpFlag: false, // true – Drücken Sie die Leertaste, um in die aufsteigende Phase zu springen; false – Phase des freien FallsdropBirdImg: require("@/assets/img/bird/bird0_0.png"),
      flyBirdImg: erfordern("@/assets/img/bird/bird0_2.png"),
      gameOver: false, // Flag, das einen Spielfehler anzeigt, wird verwendet, um Animationsframes zu stoppen};
},

1. Vögel, die sich auf und ab bewegen

Um die Position des Vogels bzw. des Rohrs zu steuern, werden die Elemente mit position: absolute positioniert.

Der Vogel selbst ist ein Div + Hintergrundbild. Anschließend definieren wir seine Anfangsposition in der Schnittstelle:

<div class="Vogel" id="Vogel" ref="Vogel"></div>
 
 #Vogel {
      Höhe: 50px;
      Breite: 50px;
      Randradius: 50 %;
      Hintergrund: URL("~assets/img/bird/bird0_1.png") keine Wiederholung, Mitte/enthalten;
      // Anfangsposition des Vogels position: absolute;
      links: 300px;
      oben: 300px;
}

Dann beginnt der Vogel ohne jegliche Aktion aus seiner Ausgangsposition zu „fallen“. Der Vogel fällt immer schneller. Hier habe ich nicht die physikalische Formel der Erdbeschleunigung verwendet, sondern einfach einen Kurvenbeschleunigungsprozess simuliert. Dies ist eine kontinuierliche Animation. Platzieren Sie diese Aktion daher im Animationsrahmen, d. h. requestAnimationFrame, und definieren Sie die Funktion jedes Rahmens als loop ().

Daher werden in der Loop-Funktion offsetTop und clientHeight des übergeordneten Elements verwendet, um zu bestimmen, ob der Vogel die oberen und unteren Bildschirmränder berührt hat. Wenn ja, endet das Spiel, wenn nicht, wird style.top erhöht, damit der Vogel fällt.

Schleife() {
      lass _this = dies;
      wenn (_this.jumpFlag) {
        // Der Vogel springt_dies.jump();
      }
      lass oben = _this.$refs.bird.offsetTop;
      if (top > _this.clientHeight - BIRD_WIDTH || top <= 0) {
        //Erreiche die Grenze, das Spiel endet_this.resetGame();
      } sonst wenn (!_this.jumpFlag) {
        _this.$refs.bird.style.background = `url('${_this.dropBirdImg}') keine Wiederholung zentrieren/enthalten`;
        _this.$refs.bird.style.top = top + startSpeed ​​* startSpeed ​​+ "px"; // Beschleunigten Fall simulieren, wenn (startSpeed ​​< UP) {
          startSpeed ​​+= GESCHWINDIGKEIT;
        }
      }
      _this.pipesMove(); // Pipeline-Bewegung}

Wenn der Spieler im Spiel die Leertaste drückt, springt der Vogel eine bestimmte Distanz hoch. Dieser Zustand wird mit this.jumpFlag[true/false] aufgezeichnet. Wenn gedrückt, wird es auf true gesetzt. In der Loop-Funktion springt der Vogel (). Nachdem er eine bestimmte Distanz gesprungen ist, wird jumpFlag auf false gesetzt und der Vogel beginnt zu fallen.

Daher ist die Sprungfunktion einfach zu implementieren:

springen() {
      lass _this = dies;
      _this.$refs.bird.style.background = `url('${_this.flyBirdImg}') keine Wiederholung zentriert/enthalten`;
      wenn (_this.jumpSum > UP_SUM) {
        // Beim Erreichen der Spitze herunterfallen_this.jumpFlag = false;
        _this.jumpSum = 0;
        Startgeschwindigkeit = 1;
      } anders {
        _this.$refs.bird.style.top = _this.$refs.bird.offsetTop - 8 + "px";
        _this.jumpSum += 8;
      }
}

2. Hintergrundbild, das sich horizontal bewegt

Das geht relativ einfach. Dazu muss in einer Endlosschleife die Hintergrundposition gewechselt werden. Die Position richtet sich nach der Breite des heruntergeladenen Hintergrundbildmaterials.

Animation: bgMove 8s linear unendlich;
      @keyframes bgMove {
        0% {
          Hintergrundposition: 805px 0;
        }
        100 % {
          Hintergrundposition: 0 0;
        }
}

Nach diesen beiden Schritten können wir einen fliegenden Vogel bekommen. Verwenden Sie document.onkeydown, um auf die Leertaste zu hören und das JumpFlag zu wechseln, wie unten gezeigt:

3. Bewegen Sie sich von rechts nach links und betreten Sie das Rohr

Die Pipeline besteht aus zwei Divs, die in der Mitte jeweils eine Lücke durch unterschiedliche top: -xx und bottom: -yy aufweisen.

Implementieren Sie zunächst eine Funktion zum Generieren einer zufälligen Gap-Pipe, die im Objekt-Array „pipeArr“ gespeichert wird:

addPipe(id) {
      lass obj = {};
      sei top_num = diese.Summe(10, 170);
      lass Höhe = diese.spaceHeight[
        Math.floor(Math.random() * dieser.RaumHöhe.Länge)
      ]; // Lückenwert nach dem Zufallsprinzip auswählen let bottom_num = height - top_num;
      obj.top = top_num;
      obj.id = ID;
      obj.rechts = -(PIPE_DISTANCE / 2);
      obj.bottom = untere_Nummer;
      dies.pipeArr.push(obj);
},
Summe(m, n) {
      // Zufallszahlen zwischen nm return Math.floor(Math.random() * (m - n) + n);
}

Dann müssen wir das Rohr verschieben, d. h. die Rohrverschiebungsfunktion pipesMove() in loop(). Die gesamte Funktion wird wie folgt implementiert:

RohreBewegen() {
      lass _this = dies;
      wenn (_this.pipeArr.length === 0) {
        zurückkehren;
      }
      lass right0 = _this.pipeArr[0].right;
      wenn (rechts0 > this.clientWidth + 300) {
        dies.pipeArr.shift();
      }
      lass right_last = _this.pipeArr[_this.pipeArr.length - 1].right;
      wenn (rechts_letzter >= PIPE_DISTANCE / 2) {
        ich würde++;
        dies.addPipe(id);
      }
      für (lass i = 0; i < _this.pipeArr.length; i++) {
        // Bestimmen Sie, ob der Vogel das Rohr berührt hat. Der Vogel ist 50*50, links: 300px; das Rohr ist 100px breit; der Rohreintrittsbereich rechts ist Breite-450 bis Breite-300
        Wenn (
          _this.pipeArr[i].right >= _this.clientWidth - 450 &&
          _this.pipeArr[i].right <= _this.clientWidth - 300
        ) {
          // Das Rohr hat den Berührungsbereich des Vogels erreicht. let bird_top = _this.$refs.bird.offsetTop;
          // 12 ist das Vogelbildmaterial mit Leerzeichen oben und unten, wenn (
            bird_top <= _this.clientHeight / 2 - _this.pipeArr[i].top - 12 ||
            Vogelspitze >=
              _this.clientHeight / 2 + _this.pipeArr[i].bottom - BIRD_WIDTH + 12
          ) {
            // drücke die Pipe_this.resetGame();
            zurückkehren;
          }
        }
        if (_this.pipeArr[i].right === _this.clientWidth - 300 && _this.pipeArr[i].right === _this.clientWidth - 301) { // Wenn sich direkt links vom Vogel ein Rohr befindet, ist das ein Beweis dafür, dass der Vogel durch das Rohr geflogen ist. Berechnen Sie die Punktzahl des Vogels basierend auf der Rohr-ID _this.score = _this.pipeArr[i].id + 1;
        }
        _this.pipeArr[i].right = _this.pipeArr[i].right + 2; // Das Rohr bewegt sich 2px pro Frame
      }
}

Hier werden fünf Dinge erledigt:

(1) Nachdem das Rohr den linken Bildschirm verlassen hat, verschieben Sie () das Rohr ganz links;

(2) Nachdem das ganz rechte Rohr eine gewisse Entfernung von der rechten Seite des Bildschirms erreicht hat, wird ein neues Rohr hinzugefügt.

(3) Während der Schleife wird festgestellt, ob der Vogel in den Bereich eines bestimmten Rohrs gelangt ist und ob die Oberseite des Vogels das obere und untere Rohr berührt. Wenn dies der Fall ist, ist das Spiel verloren.

(4) Befindet sich auf der linken Seite des Vogels ein Rohr, ist der Vogel erfolgreich durchgeflogen und die Punktzahl beträgt +1.

(5) Jeder Kanal bewegt sich 2 Pixel weit und der Wert wird im rechten Attribut aufgezeichnet.

Durch Setzen direkt im DOM:style kann das Rohr horizontal verschoben werden.

<Abschnitt Klasse="pipes-wrap" ref="pipes">
          <div
            Klasse="Pipe-Element"
            v-for="(Element, Index) in PipeArr"
            :Schlüssel="Artikel-ID"
            :id="'Rohr' + Index"
            :style="'rechts:' + item.rechts + 'px;'"
          >
            <div
              Klasse = "Rohr Rohrspitze"
              :style="'oben:-' + item.top + 'px;'"
            ></div>
            <div
              Klasse = "Rohr Rohr-Boden"
              :Stil="'unten:-' + Element.unten + 'px;'"
            ></div>
          </div>
</Abschnitt>
 
.pipes-wrap {
        Position: relativ;
        Höhe: 100%;
        Überlauf: versteckt;
        .pipe-Element {
          Position: absolut;
          Höhe: 100%;
          Breite: 100px;
          .Rohr {
            Breite: 100 %;
            Höhe: 50%;
            Position: relativ;
          }
          .Rohrspitze {
            Hintergrund: URL ('"~assets/img/bird/pipe_down.png') keine Wiederholung;
            Hintergrundgröße: 100px;
            Hintergrundposition: unten;
          }
          .Rohrboden {
            Hintergrund: URL ('"~assets/img/bird/pipe_up.png') keine Wiederholung;
            Hintergrundgröße: 100px;
            Hintergrundposition: oben;
          }
        }
} 

Das Obige ist die Idee und der Kerncode der Vue-Implementierung von Flappy Bird mit insgesamt mehr als 200 Codezeilen. Meiner Meinung nach liegt die Schwierigkeit hauptsächlich in der Bewegung der Pfeifen, der Berührungsbestimmung und der Punkteberechnung. Natürlich gibt es im Code noch viele Mängel, die optimiert werden können. Lasst uns einander ermutigen~~

Das könnte Sie auch interessieren:
  • Reines JavaScript zur Implementierung des Beispielcodes für das Spiel Flappy Bird
  • C++-Version des einfachen Flappy Bird
  • Vereinfachte Version des Flappy-Bird-Spiels in der C-Sprache
  • Python implementiert den Flappy Bird-Quellcode
  • Implementierung des Flappy-Bird-Spiels in der Sprache C
  • Unity implementiert die Spielentwicklungspraxis von Flappy Bird
  • Java-Implementierung des Quellcodes des Spiels Flappy Bird
  • Implementierung des Flappy Bird-Spiels in der Sprache C
  • Verwenden Sie Pygame, um das Flappy Bird-Spiel zu schreiben
  • Objektorientierte Implementierung fliegender Vögel von Pygame (Flappy Bird)

<<:  So fügen Sie CentOS7 systemd benutzerdefinierte Systemdienste hinzu

>>:  Detaillierte Erläuterung des Implementierungsprozesses der Dual-Master-Synchronisierung von Teiltabellen in MySQL 5.7

Artikel empfehlen

Der vollständige Implementierungsprozess von Sudoku mit JavaScript

Inhaltsverzeichnis Vorwort So lösen Sie Sudoku Fü...

React+Koa-Beispiel zur Implementierung des Datei-Uploads

Inhaltsverzeichnis Hintergrund Serverabhängigkeit...

Detaillierte Erklärung der Funktionsweise von Nginx

So funktioniert Nginx Nginx besteht aus einem Ker...

MySQL-Join-Abfrage (Left Join, Right Join, Inner Join)

1. Allgemeine Verbindungen für MySQL INNER JOIN (...

Neue Ideen zur Zeitformatierung in JavaScript toLocaleString()

Inhaltsverzeichnis 1. Konventionelle Ideen zur Ze...

Implementierungsmethode und Beispielcode des Tomcat-Klassenladers

Tomcat definiert intern mehrere ClassLoader, soda...

Detaillierte Erklärung zur Verwendung von Rastereigenschaften in CSS

Rasterlayout Dem übergeordneten Element hinzugefü...

So implementieren Sie die Kontrollkästchen- und Radioausrichtung

Nicht nur das Verhalten verschiedener Browser ist...

React-Internationalisierung react-i18next ausführliche Erklärung

Einführung react-i18next ist ein leistungsstarkes...

Detaillierte Erklärung der Lösung für das zu langsame Docker-Compose

Es gibt nur eine Lösung: die Quelle ändern! Die Q...

Einführung in CSS-Stileinführungsmethoden und ihre Vor- und Nachteile

Drei Möglichkeiten, CSS einzuführen 1. Inline-Sti...