Arbres modèles se dirigeant vers le joueurTemple des arbres se dirigeant vers le joueur ( Grand aperçu ) [19659015] Revenez à votre éditeur. Cette fois-ci, sélectionnez assets / ergo.js . Dans la section des jeux, configurez les arbres après le chargement de la fenêtre.
/ ********
* JEU *
******** /
...
window.onload = function () {
setupTrees ();
}
Sous les commandes, mais avant la section Game, ajoutez une nouvelle section TREES
. Dans cette section, définissez une nouvelle fonction setupTrees
.
/ ************
* LES CONTRÔLES *
************ /
...
/ *********
* DES ARBRES *
********* /
fonction setupTrees () {
}
/ ********
* JEU *
******** /
...
Dans la nouvelle fonction setupTrees
obtenez des références aux objets DOM de l'arbre de gabarit et rendez ces références disponibles au niveau mondial.
/ *********.
* DES ARBRES *
********* /
var templateTreeLeft;
var templateTreeCenter;
var templateTreeRight;
fonction setupTrees () {
templateTreeLeft = document.getElementById ('template-tree-left');
templateTreeCenter = document.getElementById ('template-tree-center');
templateTreeRight = document.getElementById ('template-tree-right');
}
Ensuite, définissez un nouvel utilitaire removeTree
. Avec cet utilitaire, vous pouvez ensuite supprimer les arborescences de modèles de la scène. Sous la fonction setupTrees
définissez votre nouvel utilitaire.
function setupTrees () {
...
}
fonction removeTree (arbre) {
tree.parentNode.removeChild (arbre);
}
De retour dans setupTrees
utilisez le nouvel utilitaire pour supprimer les arborescences de modèles.
function setupTrees () {
...
removeTree (templateTreeLeft);
removeTree (templateTreeRight);
removeTree (templateTreeCenter);
}
Assurez-vous que votre arbre et vos sections de jeu correspondent aux éléments suivants:
/ *********
* DES ARBRES *
********* /
var templateTreeLeft;
var templateTreeCenter;
var templateTreeRight;
fonction 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);
}
fonction removeTree (arbre) {
tree.parentNode.removeChild (arbre);
}
/ ********
* JEU *
******** /
setupControls (); // TODO: AFRAME.registerComponent doit avoir lieu avant window.onload?
window.onload = function () {
setupTrees ();
}
Rouvrez votre aperçu, et vos arbres devraient maintenant être absents. L'aperçu doit correspondre à notre jeu au début de ce didacticiel.
Produit fini de la pièce 1 ( Grand aperçu )
Ceci termine la conception de l'arborescence du modèle.
Dans cette étape, nous avons couvert et utilisé les mixins A-Frame, ce qui nous permet de simplifier le code en définissant des propriétés communes. De plus, nous avons tiré parti de l'intégration de A-Frame avec le DOM pour supprimer des objets de la scène VR de l'A-Frame.
À l'étape suivante, nous allons générer de multiples obstacles et concevoir un algorithme simple permettant de répartir les arbres entre différentes voies.
Étape 2: Obstacles lors de la ponte
Dans un jeu sans fin de coureurs, notre objectif est d’éviter que des obstacles ne nous volent. Dans cette implémentation particulière du jeu, nous utilisons trois voies comme cela est le plus courant.
Contrairement à la plupart des jeux de coureurs sans fin, ce jeu ne prend en charge que les mouvements à gauche et à droite . Cela impose une contrainte à notre algorithme pour générer des obstacles: nous ne pouvons pas avoir trois obstacles dans les trois voies, en même temps, qui volent vers nous. Si cela se produit, le joueur n'aura aucune chance de survie. En conséquence, notre algorithme de génération doit prendre en compte cette contrainte.
À cette étape, toutes les modifications de code seront effectuées dans assets / ergo.js . Le fichier HTML restera le même. Accédez à la section TREES
de assets / ergo.js .
Pour commencer, nous allons ajouter des utilitaires pour générer des arbres. Chaque arbre aura besoin d'un identifiant unique, que nous définirons naïvement comme étant le nombre d'arbres existant lors de la création de l'arbre. Commencez par suivre le nombre d'arbres dans une variable globale.
/ *********
* DES ARBRES *
********* /
...
var numberOfTrees = 0;
fonction setupTrees () {
...
Ensuite, nous allons initialiser une référence à l'élément DOM du conteneur d'arborescence, à laquelle notre fonction spawn ajoutera des arborescences. Toujours dans la section TREES
ajoutez une variable globale, puis indiquez la référence.
...
var treeContainer;
var numberOfTrees ...
fonction setupTrees () {
...
templateTreeRight = ...
treeContainer = document.getElementById ('tree-container');
removeTree (...);
...
}
En utilisant à la fois le nombre d'arbres et le conteneur d'arbres, écrivez une nouvelle fonction qui génère des arbres.
function removeTree (tree) {
...
}
fonction addTree (el) {
numberOfTrees + = 1;
el.id = 'tree-' + numberOfTrees;
treeContainer.appendChild (el);
}
...
Pour plus de facilité d'utilisation, vous allez créer une deuxième fonction qui ajoute le bon arbre à la bonne voie. Pour commencer, définissez un nouveau tableau templates
dans la section TREES
.
var templates;
var treeContainer;
...
fonction setupTrees () {
...
modèles = [templateTreeLeft, templateTreeCenter, templateTreeRight];
removeTree (...);
...
}
À l'aide de ce tableau de modèles, ajoutez un utilitaire qui génère des arbres dans une voie spécifique, à l'aide d'un identifiant représentant la gauche, le milieu ou la droite.
function fonction addTree (el) {
...
}
fonction addTreeTo (position_index) {
var template = templates [position_index];
addTree (template.cloneNode (true));
}
Accédez à votre aperçu et ouvrez votre console de développeur. Dans votre console de développeur, appelez la fonction globale addTreeTo
.
> addTreeTo (0); Nombre d'arbres apparaissant dans la voie de gauche
Invoke addTreeTo
manuellement ( Grand aperçu )
Vous allez maintenant écrire un algorithme qui fait apparaître des arbres au hasard:
Choisissez une piste au hasard (cela n'a pas encore été choisi, pour ce pas de temps);
Apparaît un arbre avec une certaine probabilité;
Si le nombre maximum d'arbres a été créé pour ce pas de temps, arrêtez. Sinon, répétez l'étape 1.
Pour appliquer cet algorithme, nous allons mélanger la liste des modèles et en traiter un par un. Commencez par définir une nouvelle fonction, addTreesRandomly
qui accepte un certain nombre d'arguments de mots clés différents.
fonction addTreeTo (position_index) {
...
}
/ **
* Ajouter n'importe quel nombre d'arbres sur différentes voies, au hasard.
** /
fonction addTreesRandomly (
{
probTreeLeft = 0,5,
probTreeCenter = 0,5,
probTreeRight = 0,5,
maxNumberTrees = 2
} = {}) {
}
Dans votre nouvelle fonction addTreesRandomly
définissez une liste d'arbres modèles et de la liste aléatoire.
fonction addTreesRandomly (...) {
arbres var = [
{probability: probTreeLeft, position_index: 0},
{probability: probTreeCenter, position_index: 1},
{probability: probTreeRight, position_index: 2},
]
mélanger (arbres);
}
Faites défiler l'écran jusqu'au bas du fichier et créez une nouvelle section d'utilitaires, ainsi qu'un nouvel utilitaire shuffle
. Cet utilitaire va mélanger un tableau en place.
/ ********
* JEU *
******** /
...
/ **************
* UTILITAIRES *
************* /
/ **
* Mélange tableau en place.
* @param {Array} un éléments Un tableau contenant les éléments.
* /
fonction shuffle (a) {
var j, x, i;
pour (i = une.longueur - 1; i> 0; i--) {
j = Math.floor (Math.random () * (i + 1));
x = a [i];
a [i] = a [j];
a [j] = x;
}
retourne un;
}
Revenez à la fonction addTreesRandomly
dans votre section Arbres. Ajoutez une nouvelle variable numberOfTreesAdded
et parcourez la liste des arbres définie ci-dessus.
function addTreesRandomly (...) {
...
var numberOfTreesAdded = 0;
trees.forEach (fonction (arbre) {
});
}
Dans l'itération au-dessus des arbres, n'engendrer un arbre qu'avec une certaine probabilité et uniquement si le nombre d'arbres ajoutés ne dépasse pas 2
. Mettez à jour la boucle for comme suit.
function addTreesRandomly (...) {
...
trees.forEach (fonction (arbre) {
if (Math.random ()
Pour conclure la fonction, retourne le nombre d'arbres ajoutés.
function addTreesRandomly (...) {
...
numéro de retour des arbres ajoutés;
}
Vérifiez que votre fonction addTreesRandomly
correspond à la suivante:
/ **
* Ajouter n'importe quel nombre d'arbres sur différentes voies, au hasard.
** /
fonction addTreesRandomly (
{
probTreeLeft = 0,5,
probTreeCenter = 0,5,
probTreeRight = 0,5,
maxNumberTrees = 2
} = {}) {
arbres var = [
{probability: probTreeLeft, position_index: 0},
{probability: probTreeCenter, position_index: 1},
{probability: probTreeRight, position_index: 2},
]
mélanger (arbres);
var numberOfTreesAdded = 0;
trees.forEach (fonction (arbre) {
if (Math.random ()
Enfin, pour générer automatiquement des arbres, configurez une minuterie qui s'exécute à intervalles réguliers. Définissez la minuterie globalement et ajoutez une nouvelle fonction de démontage pour cette minuterie.
/ * ********
* DES ARBRES *
********* /
...
var treeTimer;
fonction setupTrees () {
...
}
fonction teardownTrees () {
clearInterval (treeTimer);
}
Ensuite, définissez une nouvelle fonction qui initialise le chronomètre et le sauvegarde dans la variable globale définie précédemment. Le temporisateur ci-dessous est exécuté toutes les demi-secondes.
function addTreesRandomlyLoop ({intervalLength = 500} = {}) {
treeTimer = setInterval (addTreesRandomly, intervalLength);
}
Enfin, démarrez le chronomètre une fois la fenêtre chargée, à partir de la section Jeu.
/ ********
* JEU *
******** /
...
window.onload = function () {
...
addTreesRandomlyLoop ();
}
Accédez à votre aperçu et les arbres apparaîtront au hasard. Notez qu'il n'y a jamais trois arbres à la fois.
Arbre frayant au hasard ( Grand aperçu )
Ceci conclut l'étape des obstacles. Nous avons réussi à prendre plusieurs arbres de modèles et à générer un nombre infini d’obstacles à partir des modèles. Notre algorithme de génération respecte également les contraintes naturelles du jeu pour le rendre jouable.
Ajoutons ensuite le test de collision à la prochaine étape
Étape 3: Test de collision
Dans cette section, nous allons implémenter les tests de collision. entre les obstacles et le joueur. Ces tests de collision sont plus simples que dans la plupart des autres jeux. Cependant, le joueur ne se déplace que sur l’axe des x. Par conséquent, chaque fois qu’un arbre passe sur l’axe des x, vérifiez si la voie de l’arbre est identique à celle du joueur. Nous allons implémenter cette vérification simple pour ce jeu.
Accédez à index.html jusqu’à la section TREES
. Ici, nous allons ajouter des informations sur les voies à chacun des arbres. Pour chacun des arbres, ajoutez data-tree-position-index =
comme suit. Ajoutez également class = "tree"
afin que nous puissions facilement sélectionner tous les arbres le long de la ligne:
Accédez à assets / ergo.js et appelez une nouvelle fonction setupCollisions
dans la section GAME
. De plus, définissez une nouvelle variable globale isGameRunning
qui indique si un jeu existant est déjà en cours d'exécution.
/ ********
* JEU *
******** /
var isGameRunning = false;
setupControls ();
setupCollision ();
window.onload = function () {
...
Définissez une nouvelle section COLLISIONS
juste après la section TREES
mais avant la section Game. Dans cette section, définissez la fonction setupCollisions.
/ *********
* DES ARBRES *
********* /
...
/ ***************
* COLLISIONS *
************** /
const POSITION_Z_OUT_OF_SIGHT = 1;
const POSITION_Z_LINE_START = 0.6;
const POSITION_Z_LINE_END = 0,7;
fonction setupCollision () {
}
/ ********
* JEU *
******** /
Comme précédemment, nous allons enregistrer un composant AFRAME et utiliser l'écouteur d'événement tick
pour exécuter le code à chaque fois. Dans ce cas, nous allons enregistrer un composant avec le joueur
et exécuter des vérifications sur tous les arbres de cet écouteur:
function setupCollisions () {
AFRAME.registerComponent ('player', {
tick: fonction () {
document.querySelectorAll ('. tree'). forEach (function (tree) {
}
}
}
}
Dans la boucle pour
commencez par obtenir les informations pertinentes de l’arbre:
document.querySelectorAll ('. Tree'). ForEach (function (tree) {
position = tree.getAttribute ('position');
tree_position_index = tree.getAttribute ('data-tree-position-index');
tree_id = tree.getAttribute ('id');
}
Ensuite, toujours dans la boucle pour
supprimez l'arbre s'il est invisible, juste après l'extraction des propriétés de l'arbre:
document.querySelectorAll ('.arbor'). ForEach (fonction (arbre) {
...
if (position.z> POSITION_Z_OUT_OF_SIGHT) {
removeTree (arbre);
}
}
Ensuite, s'il n'y a pas de partie en cours, ne vérifiez pas s'il y a collision.
document.querySelectorAll ('. tree'). forEach (function (tree) {
si (! isGameRunning) retourne;
}
Enfin (toujours dans la boucle pour
), vérifiez si l'arbre partage la même position en même temps que le joueur. Si tel est le cas, appelez une fonction gameOver
à définir:
document.querySelectorAll ('. Tree'). ForEach (function (tree) {
...
if (POSITION_Z_LINE_START
Vérifiez que votre fonction setupCollisions
correspond à ce qui suit:
function setupCollisions () {
AFRAME.registerComponent ('player', {
tick: fonction () {
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 (arbre);
}
si (! isGameRunning) retourne;
if (POSITION_Z_LINE_START
Ceci termine la configuration de la collision. Nous allons maintenant ajouter quelques subtilités pour extraire les séquences startGame
et gameOver
. Accédez au GAME
. ] Mettez à jour le bloc de window.onload
pour le remplacer par le suivant, en remplaçant la fonction addTreesRandomlyLoop
par une fenêtre startGame
. .onload = function () {
setupTrees ();
démarrer jeu();
}
Sous les invocations de la fonction de configuration, créez une nouvelle fonction startGame
. Cette fonction initialisera la variable isGameRunning
en conséquence et empêchera les appels redondants.
window.onload = function () {
...
}
fonction startGame () {
if (isGameRunning) retourne;
isGameRunning = true;
addTreesRandomlyLoop ();
}
Enfin, définissez gameOver
qui alertera pour l'instant un message «Game Over!».
function startGame () {
...
}
fonction gameOver () {
isGameRunning = false;
alerte ('Game Over!');
arrachement des arbres ();
}
Ceci termine la section de test de collision du jeu sans fin de coureurs.
À cette étape, nous avons de nouveau utilisé des composants A-Frame et un certain nombre d'autres utilitaires que nous avions ajoutés précédemment. Nous avons en outre réorganisé et correctement résumé les fonctions du jeu; nous augmenterons ensuite ces fonctions de jeu pour obtenir une expérience de jeu plus complète.
Conclusion
Dans 1ère partie nous avons ajouté des commandes adaptées aux casques d'écoute virtuelle: regardez à gauche pour aller à gauche et à droite. déplacer vers la droite. Dans cette deuxième partie de la série, je vous ai montré combien il est facile de créer un jeu de réalité virtuelle de base fonctionnel. Nous avons ajouté une logique de jeu afin que le coureur sans fin corresponde à vos attentes: courez pour toujours et laissez une série infinie d'obstacles dangereux voler au joueur. Jusqu'à présent, vous avez créé un jeu fonctionnel avec une prise en charge sans clavier pour les casques de réalité virtuelle.
Voici d'autres ressources pour différents contrôles et casques VR:
Dans la partie suivante, nous allons ajouter quelques touches de finition et synchroniser. Les états de jeu qui nous rapprochent des jeux multijoueurs.
Restez à l'écoute pour la partie 3!
(rb, ra, yk, il)