text: Erstellen eines Spiels mit TypeScript. Spielschleife 2/2
  Kapitel II in der Reihe von Tutorials zum Erstellen eines Spiels von Grund auf mit TypeScript und nativen Browser-APIs
  Logo-Vektor erstellt von freepik
  Willkommen zurück! In dieser Artikelserie diskutieren wir, wie man ein einfaches rundenbasiertes Spiel mit TypeScript und nativen Browser-APIs erstellt! Kapitel II ist dem Erstellen einer Spielschleife für dieses Spiel gewidmet. Weitere Kapitel finden Sie hier:
  Kapitel II. Spielschleife ( Teil 1 , Teil 2)
  Kapitel III. Zeichnungsgitter ( Teil 1 , Teil 2 , Teil 3 , Teil 4 , Teil 5 )
  Sie können jederzeit zum game-loop-1Zweig des Repositorys wechseln . Es enthält das Arbeitsergebnis der vorherigen Beiträge und ist ein guter Ausgangspunkt für diesen.
  Entität erwacht
  Verschachtelte Entität
  Spielentität testen
  Wenn Sie sich erinnern, haben wir beim Aufbau des gameUnternehmens erhebliche Fortschritte erzielt. Wir haben sogar seine UpdateMethode vorbereitet , die alle Komponenten des rekursiv aktualisiert Game. Es ist jedoch keine große Hilfe, da niemand einen ersten Anruf tätigt, um die Schleife zu starten!
  Wir haben auch festgestellt, dass es möglich ist, die Schleife mit Hilfe des Konstruktors zu starten:
  Ein besserer Ansatz wäre die Bereitstellung einer dedizierten Initialisierungsmethode. Diese Methode kann die Schleife starten und viele andere Setups durchführen, während der Konstruktor schlank bleibt. Wir können diese Methode zum Beispiel beliebig aufrufen Initoder Awake. Ich werde die neueste verwenden, um die Unity3dAPI nachzuahmen .
  Alle Entitäten und Komponenten werden jetzt " wach ". Das heißt: Sie werden die öffentliche AwakeMethode haben.
  Beachten Sie, dass diese Lebenszyklusmethode keine starke Beziehung zu einem Konstruktor hat. Ein Objekt kann nur aus einem Objekt bestehen, während es während Awakeder Lebensdauer eines Objekts mehrmals ausgeführt werden kann. Es kann "einschlafen" und dann wieder aufwachen. Eines der typischen Beispiele ist die Wiederverwendung von Objekten, um die Kosten für die Speicherzuweisung beim Instanziieren des Objekts zu vermeiden ( lesen Sie: Konstruktor ausführen ).
  Es ist verlockend, einfach eine neue Methode zu Abstract Entityund Interface hinzuzufügen IComponent. Aber ebenso wie Update, Awakekann ein Teil der anderen Elemente unseres Spiels, nicht nur ECS sein. Es ist klüger, eine dedizierte IAwakeSchnittstelle zu erstellen und diese dann zu implementieren.
  Die Oberfläche ist erstaunlich einfach. Wir erwarten nicht einmal, dass bestimmte Daten weitergegeben werden:
  Alles was übrig bleibt ist, es mit dem IComponentfolgenden zu implementieren :
  und Entity:
  Beachten Sie, dass diese Entität alle ihre Komponenten aktiviert, sobald sie sich selbst aktiviert. Es ist genau so, wie Update,es ein Standardverhalten ist . Bestimmte Unternehmen können es bei Bedarf erweitern oder ändern.
  Da wir sowieso in dieser Nachbarschaft sind, lassen Sie uns auch etwas Hauswirtschaft machen. Ich werde Awake and Update unter einem Dienstprogrammmodul beitreten und es als "Lebenszyklus" bezeichnen. Wenn wir mehr solche Ereignisse benötigen, können wir sie hier hinzufügen:
  Jetzt können wir veraltete update.h.tsund löschen awake.h.ts. Unterstützen Sie außerdem die erforderlichen Barrel-Dateien, um dieses Modul ordnungsgemäß erneut zu exportieren:
  Und dann aktualisieren Sie die Verbraucher dieser Schnittstellen:
  Ah! Aber wir haben die Tests gebrochen! Das liegt daran, dass wir das Versprechen nicht erfüllen: "Jede Entität und Komponente sollte eine AwakeMethode haben". Und die Mocks haben es eindeutig nicht. Lassen Sie uns das ganz schnell beheben:
  Und wir sollten auf jeden Fall testen Awake. Ich werde den gleichen Ansatz verwenden, den wir beim Testen verwendet haben Update: Ich spioniere zuerst die entsprechenden Methoden aus, füge gefälschte Komponenten zu gefälschten Entitäten hinzu, führe die Awake-Methode der Entität aus und erwarte, dass auch die Komponenten der Komponente aufgerufen werden:
  Wenn Sie npm startzu diesem Zeitpunkt ausgeführt werden, sollte Ihr Code fehlerfrei kompiliert werden. Wenn Sie Tests durchführen npm t, sollten auch alle erfolgreich sein:
  Mit all dem können wir eine neue Lebenszyklusmethode in der Spielentität nutzen:
  Sobald das Spiel und alle seine Komponenten aufwachen, starten wir die Spielschleife:
  Eine kleine Verbesserung: Ich möchte sicherstellen, dass die Spielschleife nicht startet, bevor alle Komponenten und untergeordneten Entitäten aktiviert sind. Ich verzögere das Update bis zum nächsten Frame:
  Habe ich " Kinderwesen " gesagt ? Das ist richtig: Spiel ist eine Root-Entität, aber nicht die einzige. Es ist eine sehr konventionelle Art, Entitäten in der Hierarchie zu organisieren. Auf diese Weise können wir unter anderem alle diese Kinder aus dem Spiel heraus aktualisieren, indem wir Updatejedes einzelne von ihnen aufrufen .
  Wir werden im nächsten Kapitel mit dem Hinzufügen untergeordneter Entitäten beginnen, aber jetzt richten wir einfach eine Phase ein und stellen sicher, dass sie aktualisiert werden.
  Zeichenvektor erstellt von brgfx
  Ich füge eine öffentliche Eigenschaft hinzu, die ein Array aller untergeordneten Entitäten enthält:
  Indem wir alle untergeordneten Entitäten verfolgen, können wir problemlos alle Lebenszyklusmethoden auf sie aufrufen. Darüber hinaus haben einige von ihnen (oder sogar alle!) Ihre Kinder und rufen auch Awake / Update an.
  Zuerst sollten wir alle Kinder wecken und dies tun, bevor wir die Schleife starten:
  Und aktualisieren Sie sie dann bei jeder Iteration:
  Und jetzt haben wir endlich eine voll funktionsfähige Spielschleife, die jeden Frame wiederholt und alle Entitäten und Komponenten aktualisiert.
  Letzte Berührung: Lassen Sie uns diese Engine starten, indem wir das Spiel selbst instanziieren und aktivieren:
  Genial! Wenn Sie Ihren Code durch Ausführen ausführen npm start, sollte er ohne Probleme kompiliert werden.
  Wir haben immer noch keine Bilder, die beweisen könnten, dass wir unsere Suche erfolgreich abgeschlossen haben, daher ist der Unit-Test die einzige Hoffnung.
  Mann Vektor erstellt von freepik
  Glücklicherweise ist das Testen der Spielentität zu diesem Zeitpunkt unkompliziert. Es gibt fünf Dinge, die wir testen müssen:
  Und um das zu tun, müssen wir ein paar Vorbereitungen treffen. Lassen Sie uns zunächst gefälschte Kinder und Komponenten einrichten:
  Ich habe Komponenten erstellt und instanziiert, genau wie beim Entitätstest im vorherigen Kapitel. Ich habe auch leere Objekte erstellt, sie instanziiert und an das Spiel angehängt.
  Wir verwenden requestAnimationFrame im Spiel. Es ist ein asynchroner Rückruf, und wir müssen ihn richtig verspotten. Eine Möglichkeit besteht darin, es durch zu ersetzen jest.fnund sicherzustellen, dass sofort ein Rückruf ausgelöst wird:
  Auf diese Weise kann ich testen, ob die Aktualisierungsschleife ordnungsgemäß funktioniert:
  Hier spioniere ich einfach aus game.Update, wecke das Spiel und erwarte game.Update, dass es tatsächlich ausgeführt wird.
  Das Testen der anderen vier Szenarien ähnelt dem Testen von Entity, das wir im vorherigen Kapitel durchgeführt haben:
  Ich fange an, indem Sie auf Spionage Awakeoder Updatejedes Kindes / Komponente und erwarten , dass sie nach aufgerufen werden game.Awakeoder game.Updatesind.
  Warum sollten wir Awake / Update von Komponenten testen? Wir haben dasselbe bereits an einer abstrakten Entität getestet. Warum wiederholen?
  Der Grund ist, dass wir diese Funktionalität in Game's Awake / Update überschreiben könnten . Denken Sie daran, dass die abstrakte Entität nur Standardverhalten bietet. Wenn wir die Methode überschreiben (wie wir es getan haben), sollten wir sicherstellen, dass wir nichts verlieren.
  Wenn Sie Ihre Tests mit dem ausführen npm t, sollten alle erfolgreich sein:
  Y ou kann den vollständigen Quellcode dieser Beitrag in dem finden game-loop-2Zweig des Repository .
  Sie sollten stolz auf sich selbst sein, Sie haben VIEL erreicht : Sie haben etwas über Game Loop gelernt und wie es in einem Team mit der Entität und den Komponenten spielt, wie man Code in jedem Frame ausführt, Lebenszyklusmethoden von Entity entdeckt und wie man sie mit dem Spiel verwendet Loop, und natürlich, bauen Sie die Kern-Game-Entität und decken Sie sie mit Tests ab! Erstaunlicher Fortschritt!
  Das nächste Mal werden wir endlich etwas auf den Bildschirm zeichnen und die Schönheit der Komponenten in Aktion sehen.
  Dies ist das Kapitel II in der Reihe der Tutorials " Erstellen eines Spiels mit TypeScript ". Weitere Kapitel finden Sie hier: