So erstellen Sie ein Endless-Runner-Spiel in der virtuellen Realität (Teil 2)
Veröffentlicht: 2022-03-10In Teil 1 dieser Serie haben wir gesehen, wie ein Virtual-Reality-Modell mit Licht- und Animationseffekten erstellt werden kann. In diesem Teil werden wir die Kernlogik des Spiels implementieren und fortgeschrittenere A-Frame-Umgebungsmanipulationen verwenden, um den „Spiel“-Teil dieser Anwendung zu erstellen. Am Ende haben Sie ein funktionierendes Virtual-Reality-Spiel mit einer echten Herausforderung.
Dieses Tutorial umfasst eine Reihe von Schritten, einschließlich (aber nicht beschränkt auf) Kollisionserkennung und weitere A-Frame-Konzepte wie Mixins.
- Demo des Endprodukts
Voraussetzungen
Genau wie im vorherigen Tutorial benötigen Sie Folgendes:
- Internetzugang (insbesondere zu glitch.com);
- Ein Glitch-Projekt, das aus Teil 1 abgeschlossen wurde. (Sie können mit dem fertigen Produkt fortfahren, indem Sie zu https://glitch.com/edit/#!/ergo-1 navigieren und auf „Remix to edit“ klicken;
- Ein Virtual-Reality-Headset (optional, empfohlen). (Ich verwende Google Cardboard, das für 15 $ pro Stück angeboten wird.)
Schritt 1: Entwerfen der Hindernisse
In diesem Schritt entwerfen Sie die Bäume, die wir als Hindernisse verwenden werden. Dann fügen Sie eine einfache Animation hinzu, die die Bäume in Richtung des Spielers bewegt, wie die folgende:
Diese Bäume dienen als Vorlagen für Hindernisse, die Sie während des Spiels erzeugen. Für den letzten Teil dieses Schrittes entfernen wir dann diese „Vorlagenbäume“.
Fügen Sie zunächst eine Reihe verschiedener A-Frame-Mixins hinzu . Mixins sind häufig verwendete Sätze von Komponenteneigenschaften. In unserem Fall haben alle unsere Bäume die gleiche Farbe, Höhe, Breite, Tiefe usw. Mit anderen Worten, alle Ihre Bäume sehen gleich aus und verwenden daher einige gemeinsame Mixins.
Hinweis : In unserem Tutorial sind Ihre einzigen Assets Mixins. Besuchen Sie die A-Frame-Mixins-Seite, um mehr zu erfahren.
Navigieren Sie in Ihrem Editor zu index.html . Fügen Sie direkt nach Ihrem Himmel und vor Ihren Lichtern eine neue A-Frame-Entität hinzu, um Ihre Assets zu speichern:
<a-sky...></a-sky> <!-- Mixins --> <a-assets> </a-assets> <!-- Lights --> ...
Beginnen Sie in Ihrer neuen a-assets
Entität mit dem Hinzufügen eines Mixins für Ihr Blattwerk. Dieses Mixins definiert allgemeine Eigenschaften für das Blattwerk des Vorlagenbaums. Kurz gesagt, es ist eine weiße, flach schattierte Pyramide für einen Low-Poly-Effekt.
<a-assets> <a-mixin geometry=" primitive: cone; segments-height: 1; segments-radial:4; radius-bottom:0.3;" material="color:white;flat-shading: true;"></a-mixin> </a-assets>
Fügen Sie direkt unter Ihrem Laub-Mixin ein Mixin für den Stamm hinzu. Dieser Stamm wird ein kleines, weißes, rechteckiges Prisma sein.
<a-assets> ... <a-mixin geometry=" primitive: box; height:0.5; width:0.1; depth:0.1;" material="color:white;"></a-mixin> </a-assets>
Fügen Sie als Nächstes die Vorlagenbaumobjekte hinzu, die diese Mixins verwenden. Scrollen Sie immer noch in index.html nach unten zum Abschnitt Plattformen. Fügen Sie direkt vor dem Spielerabschnitt einen neuen Baumabschnitt mit drei leeren Baumelementen hinzu:
<a-entity ...> <!-- Trees --> <a-entity></a-entity> <a-entity></a-entity> <a-entity></a-entity> <!-- Player --> ...
Positionieren Sie als Nächstes die Baumelemente neu, skalieren Sie sie neu und fügen Sie Schatten hinzu.
<!-- Trees --> <a-entity shadow scale="0.3 0.3 0.3" position="0 0.6 0"></a-entity> <a-entity shadow scale="0.3 0.3 0.3" position="0 0.6 0"></a-entity> <a-entity shadow scale="0.3 0.3 0.3" position="0 0.6 0"></a-entity>
Füllen Sie nun die Baumentitäten mit einem Stamm und Blättern, indem Sie die zuvor definierten Mixins verwenden.
<!-- Trees --> <a-entity ...> <a-entity mixin="foliage"></a-entity> <a-entity mixin="trunk" position="0 -0.5 0"></a-entity> </a-entity> <a-entity ...> <a-entity mixin="foliage"></a-entity> <a-entity mixin="trunk" position="0 -0.5 0"></a-entity> </a-entity> <a-entity ...> <a-entity mixin="foliage"></a-entity> <a-entity mixin="trunk" position="0 -0.5 0"></a-entity> </a-entity>
Navigieren Sie zu Ihrer Vorschau und Sie sollten nun die folgenden Vorlagenbäume sehen.
Animieren Sie nun die Bäume von einem entfernten Ort auf der Plattform in Richtung des Benutzers. Verwenden Sie wie zuvor das a-animation
Tag:
<!-- Trees --> <a-entity ...> ... <a-animation attribute="position" ease="linear" from="0 0.6 -7" to="0 0.6 1.5" dur="5000"></a-animation> </a-entity> <a-entity ...> ... <a-animation attribute="position" ease="linear" from="-0.5 0.55 -7" to="-0.5 0.55 1.5" dur="5000"></a-animation> </a-entity> <a-entity ...> ... <a-animation attribute="position" ease="linear" from="0.5 0.55 -7" to="0.5 0.55 1.5" dur="5000"></a-animation> </a-entity>
Stellen Sie sicher, dass Ihr Code mit dem Folgenden übereinstimmt.
<a-entity...> <!-- Trees --> <a-entity shadow scale="0.3 0.3 0.3" position="0 0.6 0"> <a-entity mixin="foliage"></a-entity> <a-entity mixin="trunk" position="0 -0.5 0"></a-entity> <a-animation attribute="position" ease="linear" from="0 0.6 -7" to="0 0.6 1.5" dur="5000"></a-animation> </a-entity> <a-entity shadow scale="0.3 0.3 0.3" position="-0.5 0.55 0"> <a-entity mixin="foliage"></a-entity> <a-entity mixin="trunk" position="0 -0.5 0"></a-entity> <a-animation attribute="position" ease="linear" from="-0.5 0.55 -7" to="-0.5 0.55 1.5" dur="5000"></a-animation> </a-entity> <a-entity shadow scale="0.3 0.3 0.3" position="0.5 0.55 0"> <a-entity mixin="foliage"></a-entity> <a-entity mixin="trunk" position="0 -0.5 0"></a-entity> <a-animation attribute="position" ease="linear" from="0.5 0.55 -7" to="0.5 0.55 1.5" dur="5000"></a-animation> </a-entity> <!-- Player --> ...
Navigieren Sie zu Ihrer Vorschau und Sie sehen nun, wie sich die Bäume auf Sie zubewegen.
Navigieren Sie zurück zu Ihrem Editor. Wählen Sie diesmal assets/ergo.js aus . Richten Sie im Spielbereich Bäume ein, nachdem das Fenster geladen wurde.
/******** * GAME * ********/ ... window.onload = function() { setupTrees(); }
Fügen Sie unter den Steuerelementen, aber vor dem Abschnitt „Spiel“ einen neuen Abschnitt „ TREES
“ hinzu. Definieren Sie in diesem Abschnitt eine neue setupTrees
Funktion.
/************ * CONTROLS * ************/ ... /********* * TREES * *********/ function setupTrees() { } /******** * GAME * ********/ ...
Rufen Sie in der neuen setupTrees
Funktion Verweise auf die DOM-Objekte der Vorlagenstruktur ab und stellen Sie die Verweise global zur Verfügung.
/********* * TREES * *********/ var templateTreeLeft; var templateTreeCenter; var templateTreeRight; function setupTrees() { templateTreeLeft = document.getElementById('template-tree-left'); templateTreeCenter = document.getElementById('template-tree-center'); templateTreeRight = document.getElementById('template-tree-right'); }
Definieren Sie als Nächstes ein neues removeTree
Dienstprogramm. Mit diesem Dienstprogramm können Sie dann die Vorlagenbäume aus der Szene entfernen. Definieren Sie unter der Funktion setupTrees
Ihr neues Dienstprogramm.
function setupTrees() { ... } function removeTree(tree) { tree.parentNode.removeChild(tree); }
Zurück in setupTrees
verwenden Sie das neue Dienstprogramm, um die Vorlagenbäume zu entfernen.
function setupTrees() { ... removeTree(templateTreeLeft); removeTree(templateTreeRight); removeTree(templateTreeCenter); }
Stellen Sie sicher, dass Ihre Baum- und Spielabschnitte mit Folgendem übereinstimmen:
/********* * TREES * *********/ var templateTreeLeft; var templateTreeCenter; var templateTreeRight; function setupTrees() { templateTreeLeft = document.getElementById('template-tree-left'); templateTreeCenter = document.getElementById('template-tree-center'); templateTreeRight = document.getElementById('template-tree-right'); removeTree(templateTreeLeft); removeTree(templateTreeRight); removeTree(templateTreeCenter); } function removeTree(tree) { tree.parentNode.removeChild(tree); } /******** * GAME * ********/ setupControls(); // TODO: AFRAME.registerComponent has to occur before window.onload? window.onload = function() { setupTrees(); }
Öffnen Sie Ihre Vorschau erneut, und Ihre Bäume sollten jetzt fehlen. Die Vorschau sollte zu unserem Spiel zu Beginn dieses Tutorials passen.
Damit ist das Design des Vorlagenbaums abgeschlossen.
In diesem Schritt haben wir A-Frame-Mixins behandelt und verwendet, mit denen wir den Code vereinfachen können, indem wir gemeinsame Eigenschaften definieren. Darüber hinaus haben wir die A-Frame-Integration mit dem DOM genutzt, um Objekte aus der A-Frame-VR-Szene zu entfernen.
Im nächsten Schritt werden wir mehrere Hindernisse spawnen und einen einfachen Algorithmus entwerfen, um Bäume auf verschiedene Fahrspuren zu verteilen.
Schritt 2: Spawning-Hindernisse
In einem endlosen Läuferspiel ist es unser Ziel, Hindernissen auszuweichen, die auf uns zufliegen. In dieser speziellen Implementierung des Spiels verwenden wir drei Bahnen, wie es am häufigsten üblich ist.
Im Gegensatz zu den meisten Endlos-Runner-Spielen unterstützt dieses Spiel nur Bewegungen nach links und rechts . Dies erlegt unserem Algorithmus zum Spawnen von Hindernissen eine Einschränkung auf: Wir können nicht drei Hindernisse gleichzeitig auf allen drei Spuren auf uns zufliegen lassen. In diesem Fall hätte der Spieler keine Überlebenschance. Infolgedessen muss unser Spawning-Algorithmus diese Einschränkung berücksichtigen.
In diesem Schritt werden alle unsere Codebearbeitungen in assets/ergo.js vorgenommen . Die HTML-Datei bleibt gleich. Navigieren Sie zum Abschnitt TREES
von assets/ergo.js .
Zu Beginn werden wir Dienstprogramme zu Spawn-Bäumen hinzufügen. Jeder Baum benötigt eine eindeutige ID, die wir naiverweise als die Anzahl der Bäume definieren, die vorhanden sind, wenn der Baum erzeugt wird. Beginnen Sie damit, die Anzahl der Bäume in einer globalen Variablen zu verfolgen.
/********* * TREES * *********/ ... var numberOfTrees = 0; function setupTrees() { ...
Als Nächstes initialisieren wir einen Verweis auf das DOM-Element des Baumcontainers, dem unsere Spawn-Funktion Bäume hinzufügen wird. Fügen Sie noch im Abschnitt TREES
eine globale Variable hinzu und stellen Sie dann die Referenz her.
... var treeContainer; var numberOfTrees ... function setupTrees() { ... templateTreeRight = ... treeContainer = document.getElementById('tree-container'); removeTree(...); ... }
Schreiben Sie unter Verwendung der Anzahl der Bäume und des Baumcontainers eine neue Funktion, die Bäume spawnt.
function removeTree(tree) { ... } function addTree(el) { numberOfTrees += 1; el.id = 'tree-' + numberOfTrees; treeContainer.appendChild(el); } ...
Für eine spätere Benutzerfreundlichkeit erstellen Sie eine zweite Funktion, die den richtigen Baum zur richtigen Bahn hinzufügt. Definieren Sie zunächst ein neues templates
-Array im Abschnitt TREES
.
var templates; var treeContainer; ... function setupTrees() { ... templates = [templateTreeLeft, templateTreeCenter, templateTreeRight]; removeTree(...); ... }
Fügen Sie mithilfe dieses Template-Arrays ein Dienstprogramm hinzu, das Bäume in einer bestimmten Spur spawnt, wobei eine ID angegeben wird, die links, Mitte oder rechts darstellt.
function function addTree(el) { ... } function addTreeTo(position_index) { var template = templates[position_index]; addTree(template.cloneNode(true)); }
Navigieren Sie zu Ihrer Vorschau und öffnen Sie Ihre Entwicklerkonsole. Rufen Sie in Ihrer Entwicklerkonsole die globale addTreeTo
Funktion auf.
> addTreeTo(0); # spawns tree in left lane
Jetzt schreiben Sie einen Algorithmus, der zufällig Bäume erzeugt:
- Wähle zufällig eine Spur (die für diesen Zeitschritt noch nicht ausgewählt wurde);
- Spawne mit einiger Wahrscheinlichkeit einen Baum;
- Wenn die maximale Anzahl an Bäumen für diesen Zeitschritt gespawnt wurde, stoppen Sie. Wiederholen Sie andernfalls Schritt 1.
Um diesen Algorithmus zu bewirken, werden wir stattdessen die Liste der Vorlagen mischen und eine nach der anderen verarbeiten. Beginnen Sie mit der Definition einer neuen Funktion, addTreesRandomly
, die eine Reihe verschiedener Schlüsselwortargumente akzeptiert.
function addTreeTo(position_index) { ... } /** * Add any number of trees across different lanes, randomly. **/ function addTreesRandomly( { probTreeLeft = 0.5, probTreeCenter = 0.5, probTreeRight = 0.5, maxNumberTrees = 2 } = {}) { }
Definieren Sie in Ihrer neuen addTreesRandomly
Funktion eine Liste von Vorlagenbäumen und mischen Sie die Liste.
function addTreesRandomly( ... ) { var trees = [ {probability: probTreeLeft, position_index: 0}, {probability: probTreeCenter, position_index: 1}, {probability: probTreeRight, position_index: 2}, ] shuffle(trees); }
Scrollen Sie zum Ende der Datei und erstellen Sie einen neuen Abschnitt mit Dienstprogrammen sowie ein neues shuffle
für die Zufallswiedergabe. Dieses Dienstprogramm mischt ein Array an Ort und Stelle.
/******** * GAME * ********/ ... /************* * UTILITIES * *************/ /** * Shuffles array in place. * @param {Array} a items An array containing the items. */ function shuffle(a) { var j, x, i; for (i = a.length - 1; i > 0; i--) { j = Math.floor(Math.random() * (i + 1)); x = a[i]; a[i] = a[j]; a[j] = x; } return a; }
Navigieren Sie zurück zur addTreesRandomly
Funktion in Ihrem Trees-Abschnitt. Fügen Sie eine neue Variable numberOfTreesAdded
und durchlaufen Sie die Liste der oben definierten Bäume.
function addTreesRandomly( ... ) { ... var numberOfTreesAdded = 0; trees.forEach(function (tree) { }); }
Spawne bei der Iteration über Bäume einen Baum nur mit einer gewissen Wahrscheinlichkeit und nur dann, wenn die Anzahl der hinzugefügten Bäume 2
nicht überschreitet. Aktualisieren Sie die for-Schleife wie folgt.
function addTreesRandomly( ... ) { ... trees.forEach(function (tree) { if (Math.random() < tree.probability && numberOfTreesAdded < maxNumberTrees) { addTreeTo(tree.position_index); numberOfTreesAdded += 1; } }); }
Um die Funktion abzuschließen, geben Sie die Anzahl der hinzugefügten Bäume zurück.
function addTreesRandomly( ... ) { ... return numberOfTreesAdded; }
Überprüfen Sie noch einmal, ob Ihre addTreesRandomly
Funktion mit dem Folgenden übereinstimmt.
/** * Add any number of trees across different lanes, randomly. **/ function addTreesRandomly( { probTreeLeft = 0.5, probTreeCenter = 0.5, probTreeRight = 0.5, maxNumberTrees = 2 } = {}) { var trees = [ {probability: probTreeLeft, position_index: 0}, {probability: probTreeCenter, position_index: 1}, {probability: probTreeRight, position_index: 2}, ] shuffle(trees); var numberOfTreesAdded = 0; trees.forEach(function (tree) { if (Math.random() < tree.probability && numberOfTreesAdded < maxNumberTrees) { addTreeTo(tree.position_index); numberOfTreesAdded += 1; } }); return numberOfTreesAdded; }
Um schließlich Bäume automatisch zu spawnen, richten Sie einen Timer ein, der das Spawnen von Bäumen in regelmäßigen Abständen auslöst. Definieren Sie den Timer global und fügen Sie eine neue Teardown-Funktion für diesen Timer hinzu.
/********* * TREES * *********/ ... var treeTimer; function setupTrees() { ... } function teardownTrees() { clearInterval(treeTimer); }
Definieren Sie als Nächstes eine neue Funktion, die den Timer initialisiert und den Timer in der zuvor definierten globalen Variablen speichert. Der untenstehende Timer wird jede halbe Sekunde ausgeführt.
function addTreesRandomlyLoop({intervalLength = 500} = {}) { treeTimer = setInterval(addTreesRandomly, intervalLength); }
Starten Sie schließlich den Timer, nachdem das Fenster geladen wurde, aus dem Abschnitt Spiel.
/******** * GAME * ********/ ... window.onload = function() { ... addTreesRandomlyLoop(); }
Navigieren Sie zu Ihrer Vorschau und Sie sehen zufällig Bäume spawnen. Beachten Sie, dass es nie drei Bäume gleichzeitig gibt.
Damit ist der Hindernisschritt abgeschlossen. Wir haben erfolgreich eine Reihe von Vorlagenbäumen genommen und eine unendliche Anzahl von Hindernissen aus den Vorlagen generiert. Unser Spawning-Algorithmus respektiert auch natürliche Einschränkungen im Spiel, um es spielbar zu machen.
Im nächsten Schritt fügen wir Kollisionstests hinzu.
Schritt 3: Kollisionstest
In diesem Abschnitt implementieren wir die Kollisionstests zwischen den Hindernissen und dem Spieler. Diese Kollisionstests sind einfacher als Kollisionstests in den meisten anderen Spielen; Der Spieler bewegt sich jedoch nur entlang der X-Achse. Überprüfen Sie also, wann immer ein Baum die X-Achse kreuzt, ob die Spur des Baums mit der Spur des Spielers übereinstimmt. Wir werden diese einfache Überprüfung für dieses Spiel implementieren.
Navigieren Sie zu index.html bis zum Abschnitt TREES
. Hier fügen wir Spurinformationen zu jedem der Bäume hinzu. Fügen Sie für jeden Baum wie folgt data-tree-position-index=
hinzu. Fügen Sie zusätzlich class="tree"
hinzu, damit wir alle Bäume auf der ganzen Linie einfach auswählen können:
<a-entity data-tree-position-index="1" class="tree" ...> </a-entity> <a-entity data-tree-position-index="0" class="tree" ...> </a-entity> <a-entity data-tree-position-index="2" class="tree" ...> </a-entity>
Navigieren Sie zu assets/ergo.js und rufen Sie eine neue setupCollisions
Funktion im Abschnitt GAME
auf. Definieren Sie außerdem eine neue globale Variable isGameRunning
, die angibt, ob ein vorhandenes Spiel bereits ausgeführt wird oder nicht.
/******** * GAME * ********/ var isGameRunning = false; setupControls(); setupCollision(); window.onload = function() { ...
Definieren Sie einen neuen COLLISIONS
-Abschnitt direkt nach dem TREES
Abschnitt, aber vor dem Spiel-Abschnitt. Definieren Sie in diesem Abschnitt die Funktion setupCollisions.
/********* * TREES * *********/ ... /************** * COLLISIONS * **************/ const POSITION_Z_OUT_OF_SIGHT = 1; const POSITION_Z_LINE_START = 0.6; const POSITION_Z_LINE_END = 0.7; function setupCollision() { } /******** * GAME * ********/
Wie zuvor werden wir eine AFRAME-Komponente registrieren und den tick
-Ereignis-Listener verwenden, um Code in jedem Zeitschritt auszuführen. In diesem Fall registrieren wir eine Komponente beim player
und führen Prüfungen für alle Bäume in diesem Listener durch:
function setupCollisions() { AFRAME.registerComponent('player', { tick: function() { document.querySelectorAll('.tree').forEach(function(tree) { } } } }
Beginnen Sie in der for
-Schleife damit, die relevanten Informationen des Baums abzurufen:
document.querySelectorAll('.tree').forEach(function(tree) { position = tree.getAttribute('position'); tree_position_index = tree.getAttribute('data-tree-position-index'); tree_id = tree.getAttribute('id'); }
Entfernen Sie als Nächstes, immer noch innerhalb der for
-Schleife, den Baum, wenn er nicht sichtbar ist, direkt nach dem Extrahieren der Eigenschaften des Baums:
document.querySelectorAll('.tree').forEach(function(tree) { ... if (position.z > POSITION_Z_OUT_OF_SIGHT) { removeTree(tree); } }
Als nächstes, wenn kein Spiel läuft, prüfen Sie nicht, ob es eine Kollision gibt.
document.querySelectorAll('.tree').forEach(function(tree) { if (!isGameRunning) return; }
Überprüfen Sie abschließend (immer noch in der for
-Schleife), ob der Baum zur gleichen Zeit dieselbe Position wie der Spieler hat. Rufen Sie in diesem Fall eine noch zu definierende gameOver
-Funktion auf:
document.querySelectorAll('.tree').forEach(function(tree) { ... if (POSITION_Z_LINE_START < position.z && position.z < POSITION_Z_LINE_END && tree_position_index == player_position_index) { gameOver(); } }
Überprüfen Sie, ob Ihre setupCollisions
Funktion mit Folgendem übereinstimmt:
function setupCollisions() { AFRAME.registerComponent('player', { tick: function() { document.querySelectorAll('.tree').forEach(function(tree) { position = tree.getAttribute('position'); tree_position_index = tree.getAttribute('data-tree-position-index'); tree_id = tree.getAttribute('id'); if (position.z > POSITION_Z_OUT_OF_SIGHT) { removeTree(tree); } if (!isGameRunning) return; if (POSITION_Z_LINE_START < position.z && position.z < POSITION_Z_LINE_END && tree_position_index == player_position_index) { gameOver(); } }) } }) }
Damit ist die Kollisionseinstellung abgeschlossen. Jetzt werden wir ein paar Feinheiten hinzufügen, um die startGame
und gameOver
Sequenzen zu abstrahieren. Navigieren Sie zum Abschnitt GAME
. Aktualisieren Sie den window.onload
Block so, dass er dem Folgenden entspricht, und ersetzen addTreesRandomlyLoop
durch eine noch zu definierende startGame
-Funktion.
window.onload = function() { setupTrees(); startGame(); }
Erstellen Sie unter den Setup-Funktionsaufrufen eine neue startGame
Funktion. Diese Funktion initialisiert die isGameRunning
Variable entsprechend und verhindert redundante Aufrufe.
window.onload = function() { ... } function startGame() { if (isGameRunning) return; isGameRunning = true; addTreesRandomlyLoop(); }
Definieren Sie schließlich gameOver
, wodurch ein „Game Over!“ gemeldet wird. Nachricht für jetzt.
function startGame() { ... } function gameOver() { isGameRunning = false; alert('Game Over!'); teardownTrees(); }
Damit ist der Kollisionstestabschnitt des Endlos-Runner-Spiels abgeschlossen.
In diesem Schritt haben wir wieder A-Frame-Komponenten und eine Reihe anderer Dienstprogramme verwendet, die wir zuvor hinzugefügt haben. Außerdem haben wir die Spielfunktionen neu organisiert und richtig abstrahiert; Wir werden diese Spielfunktionen anschließend erweitern, um ein vollständigeres Spielerlebnis zu erreichen.
Fazit
In Teil 1 haben wir VR-Headset-freundliche Steuerungen hinzugefügt: Nach links schauen, um sich nach links zu bewegen, und nach rechts, um sich nach rechts zu bewegen. In diesem zweiten Teil der Serie habe ich Ihnen gezeigt, wie einfach es sein kann, ein einfaches, funktionierendes Virtual-Reality-Spiel zu bauen. Wir haben Spiellogik hinzugefügt, damit der Endlosläufer Ihren Erwartungen entspricht: Laufen Sie für immer und lassen Sie eine endlose Reihe gefährlicher Hindernisse auf den Spieler fliegen. Bisher haben Sie ein funktionierendes Spiel mit tastaturloser Unterstützung für Virtual-Reality-Headsets entwickelt.
Hier sind zusätzliche Ressourcen für verschiedene VR-Steuerungen und Headsets:
- A-Frame für VR-Headsets
Eine Umfrage zu Browsern und Headsets, die von A-Frame VR unterstützt werden. - A-Frame für VR-Controller
Wie A-Frame neben anderen Alternativen für die Interaktion keine Controller, 3DoF-Controller und 6DoF-Controller unterstützt.
Im nächsten Teil werden wir noch ein paar Feinschliffe hinzufügen und Spielstände synchronisieren, was uns Multiplayer-Spielen einen Schritt näher bringt.