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

Deaktivieren der AutoVervollständigen-Funktion im Eingabefeld

Jetzt können wir ein Eingabeattribut namens „Autov...

Wie MySQL implizite Standardwerte verarbeitet

Einige Studenten sagten, dass sie auf das Problem...

Detaillierte Erläuterung der MySQL-Benutzerrechteverwaltung

Inhaltsverzeichnis Vorwort: 1. Einführung in die ...

Vue+Router+Element zur Implementierung einer einfachen Navigationsleiste

Dieses Projekt teilt den spezifischen Code von Vu...

Was bedeutet das n nach int(n) in MySQL?

Sie wissen vielleicht bereits, dass die Länge 1 v...

Eine einfache Methode zum Ändern der Größe hochgeladener Nginx-Dateien

Originallink: https://vien.tech/article/138 Vorwo...

JS 4 super praktische Tipps zur Verbesserung der Entwicklungseffizienz

Inhaltsverzeichnis 1. Kurzschlussurteil 2. Option...

Lösen Sie das Problem inkonsistenter Front- und Back-End-Ports von Vue

Die Front- und Back-End-Ports von Vue sind inkons...

Detaillierte Erklärung zur Verwendung mehrerer Timer in CocosCreator

1. setTimeOut Drucken Sie abc nach 3 Sekunden. Nu...

Neuer Ansatz zum Umschalten der Tab-Leiste mit zwei Auswahlmöglichkeiten in Vue

Problembeschreibung Wenn wir an einem Projekt arb...

Erstellen Sie mit Node.JS ein Echtzeit-Warnsystem für Unwetter

Inhaltsverzeichnis Vorwort: Schritt 1: Finden Sie...