Le projet

Notre projet consistait en l'implémentation d'un jeu de bataille navale utilisant le matériel de réalité virtuelle mis à notre disposition.
Vous trouverez sur cette page:

Le cahier des charges

L'idée:

L'idée de départ est de créer un jeu de bataille navale immersif. Les joueurs sont plongés dans un environnement virtuel. Ils peuvent interagir avec un plateau virtuel horizontal représentant leur mer et la position de leurs bateaux (sur une grille 10x10), et un plateau virtuel vertical représentant la mer de l'adversaire (une grille 10x10 également). Dans un premier temps, le joueur place ses bateaux sur sa grille horizontale avec les mains. Ensuite, il lancera ses bombes sur la grille de l'adversaire.

Les outils:

Nous utiliserons le visiocasque pour le rendu graphique, un fob pour tracker la position de la tête, et le gant pour déterminer la position des doigts (des articulations). Nous aurons également besoin de tracker la position de la main, mais puisqu'il est impossible d'utiliser un deuxième fob, nous avons pensé à un système de pictogramme placé sur la main, et filmé par une caméra fixe et/ou par la caméra du visiocasque.

Les interactions:

Les bateaux sont des objets virtuels initialement posés à coté de la grille du joueur. Le joueur peut manipuler ses bateaux en plaçant sa main dessus puis en serrant les doigts (on utilisera le gant). Une fois le bateau « en main », il peut le déplacer et le tourner. Lorsqu'il le lâche au dessus de la grille, le bateau tombe dessus et se place sur les cases les plus proches. Si le joueur lâche le bateau en diagonale sur la grille, le bateau se placera de lui même parfaitement vertical ou parfaitement horizontal sur la grille. Si le joueur lâche le bateau à coté de la grille, il reviendra dans sa position initiale à coté de la grille.

Une fois la position des bateaux validée, le joueur ne peut plus les manipuler. En revanche, il peut lancer des bombes sur la grille de l'adversaire. Soit en indiquant la case visée, soit en jetant la bombe dessus (elle aura une trajectoire parabolique). Le joueur voit la grille de l'adversaire en face de lui. En levant le bras et en pointant du doigt une case, celle-ci se place en surbrillance. Si le joueur étend complètement la main, une bombe est lancée sur cette case. Une autre option permet au joueur de « lancer » la bombe à la main. En reculant son bras et en serrant la main, puis en projetant son bras en avant et en détendant les doigts. La trajectoire de l'objet lancé sera calculée et se terminera sur une case de la grille de l'adversaire. Une bombe sera lancée sur cette case.

A tout moment du jeu , le joueur a accès à un « tableau de bord » représenté par des boutons placés autour de sa grille. Ces boutons représentent les options du jeu (« Nouvelle partie », « sauvegarder partie », « difficulté de l'IA », « taille de la grille », etc...). Le joueur peut appuyer sur ces boutons, et déclencher les options, en plaçant sa main dessus puis en la déplaçant en direction du bouton. Si la main « traverse » le bouton de haut en bas, on considère que le joueur « appuie » dessus.

MUST:

SHOULD:

MAY:

Planning

Avant lundi 23/11:

Lundi 23/11:

Mardi 24/11:

Mercredi 25/11:

Ensuite:

Télécharger

La version .doc du cahier des charges est disponible ici.

Nos choix d'implémentation

Architecture de notre programme

Nous avons choisi pour notre code une architecture plutôt modulaire. Nous disposons donc de modules pour:

Chaque module gère les interactions avec l'objet et son affichage s'il le faut. Comme il s'agit de notre premier projet d'affichage d'objets en OpenGL, nous avons beaucoup hésité sur la façon de gérer les objets dans l'espace (notre code comprend encore quelques incohérences à ce niveau). Finalement, chaque objet affichable s'est vu attribuer une frame qglviewer qui indique sa position et son orientation.

Affichage

Pourquoi pas QGLVIEWER ?
Nous étions tenté, dans un premier temps, d'employer l'interface de très haut niveau qglviewer afin de développer. Cependant, l'affichage sur chaque œil d'une image différente nous a beaucoup gêné. En effet, qglviewer fournit une option pour gérer la stéréoscopie, mais uniquement avec le matériel qui le supporte. Notre HMD n'est pas un appareil qui supporte la stéréoscopie puisque il propose deux écrans bien distincts. Il s'agit peut être d'une interprétation personnelle, mais la stéréoscopie me semble être le fait d'envoyer des images sur une seule sortie vidéo mais en précisant qu'on envoie les images des deux yeux simultanément. Quoiqu'il en soit, le HMD consiste en deux écrans bien distincts, donc il ne s'agit pas de stéréoscopie au même sens que le voit qglviewer. Il m'a été dit que qglviewer gérait aussi le cas de stéréoscopie avec deux écrans différents, mais je n'ai jamais trouvé de mention à ce fait dans la documentation.

Nous avons donc finalement opté pour glut, surcouche de OpenGL beaucoup plus bas niveau que qglviewer mais qui a l'avantage de gérer les subwindows (sous fenêtre dans la fenêtre principale), ce qui nous convenaient tout à fait.

Retour d'informations

Un aspect important de notre application est que nous voulions que celle ci soit la plus interactive possible avec l'utilisateur. Pour ce faire, divers retours d'information se devaient d'être réalisés. Les couleurs ont ici été très importantes pour signifier par exemple par un surlignage que le bateau était plaçable ou non, que celui ci était préhensible ou non, que l'on pouvait tirer sur la case adversaire ou pas, que le bouton du menu était activé ou non. Toutes ces informations permettaient à l'utilisateur de savoir que son action avait été vraiment prise en compte et d'éxpérimenter une vraie interaction avec l'environnement.

Afin de pouvoir configurer le jeu et fournir davantage d'interaction, nous avons choisi d'inclure un menu dans l'environnement virtuel, directement à droite de la grille du joueur. Celui ci permettant quelques actions de base comme commencer une nouvelle partie, placer les bateaux aléatoirement, changer le niveau de l'IA, quitter. Les boutons peuvent être de deux types: boutons poussoirs qui restent activés après la relache ou standards activés juste au moment de l'appui. Ici encore l'activation d'un bouton est signifiée par un changement de couleur et son appui par une division de la taille du bouton simulant l'interaction avec de vrais boutons.

Intelligence Artificielle

Nous avons décidé de proposer au joueur un adversaire virtuel au lieu de proposer la possibilité de jouer à deux. D'abord parce qu'un adversaire virtuel est toujours disponible, ensuite parce qu'il était impossible de proposer aux deux joueurs de s'affronter en utilisant tous les deux le système de réalité virtuelle. Ne serait-ce que par manque de matériel.

L'IA implémentée dispose de 3 niveaux d'"intelligence":

Au niveau de l'implémentation, l'IA gère des listes de cases de priorité variable.
Une case avoisinant un bateau tout juste atteint sera de priorité maximale: il faut tirer sur cette case au plus vite.
Une case sur une diagonale sera de priorité 1: il faut tirer dessus avant de chercher ailleurs.
Les autres cases (les coins par exemple) seront de priorité 0: si on a pas le choix, on tire dessus.
Ces listes de priorité sont mises à jour en permanence, mais elles ne sont utilisées que si le niveau d'intelligence de l'IA est suffisament élevé. Cela permet de modifier ce niveau à tout moment de la partie.

Comment jouer

Dans tout jeu de bataille navale, une première phase de jeu consiste à placer ses bateaux sur une grille. Une fois que chaque joueur a posé ses bateaux, chacun doit tirer sur la grille de l'adversaire et essayer de couler sa flotte. Bien entendu, il est impossible de savoir où sont les bateaux de l'adversaire avant de les atteindre d'un tir.

Notre jeu ne déroge pas à ces règles. Il comporte deux grilles (une par joueur), 5 bateaux de tailles différentes, et un menu comportant plusieurs options.

Les vidéos suivantes montrent ce que voit le joueur à travers le HMD (les deux yeux étant séparés). Les intéractions sont ici faites à l'aide du clavier, et non pas du matériel de réalité virtuelle, c'est pourquoi les mouvements sont linéaires et saccadés.

L'environnement de jeu

L'environnement de jeu comprend une "table" virtuelle sur laquelle repose une grille de jeu (de taille 10x10 cases). A gauche de la grille se trouvent 5 bateaux: un torpilleur de 2 cases, un sous-marin de 3 cases, un croiseur de 3 cases, une frégate de 4 cases, et un porte-avion de 6 cases. A droite de la grille se trouve un menu composé de 6 boutons (voir description plus bas). En face de la table, placée verticalement, se trouve la grille de l'adversaire (de taille 10x10 cases également).

Le joueur peut tourner autour de cet environnement comme il le souhaite, mis à part qu'il ne peut pas regarder sous la table. En effet, l'émetteur du Flock of Birds est au niveau de la grille horizontale, et le système ne peut pas interprêter correctement ce qui se passe lorsque le bird passe en dessous de l'émetteur.

Placer ses bateaux

Le joueur peut placer ses bateaux à la main, il lui suffit de placer sa main sur le bateau qu'il souhaite prendre. Lorsque c'est le cas, le bateau est "surligné" en jaune, le joueur sert alors le poing (ici, il appuie sur la touche P du clavier), le bateau suivra ensuite les mouvements de la main. Le joueur n'a plus alors qu'à déplacer sa main au dessus de la grille et relacher le bateau (ou appuyer sur la touche L). Le bateau tombera ensuite au bon endroit sur la grille.

A droite de la grille se trouve également une touche "Placement aléatoire" qui permet de positionner sur la grille les bateaux restants de façon aléatoire. Cette option permet au joueur de débuter la partie plus rapidement.

L'IA choisit également la position de ses bateaux, mais ceci se fait instantanément. Donc une fois que les bateaux du joueur sont placés, le jeu peut commencer immédiatement.

Tirer sur l'adversaire

Le but de la phase suivante consiste à tirer sur la grille de l'adversaire (grille verticale) en pointant du doigt la case visée. Le joueur valide le tir en touchant son index avec son pouce s'il porte le gant, en appuyant sur la touche M du clavier sinon. Si la case visée était disponible, alors le tir devient effectif, et une théière partant de la main du joueur vient s'écraser sur la case.

Si le joueur a atteint un bateau, il peut alors rejouer. Il lui suffit de remettre sa main en position de repos, de viser une nouvelle case, et de tirer à nouveau.
Une fois que le joueur a tiré dans l'eau, c'est au tour de l'adversaire de joueur. L'IA choisit une case en fonction de son niveau d'intelligence, et tire dessus. Une thière apparait au dessus de la table virtuelle et tombe sur la case visée. Comme le joueur, l'IA rejoue tant qu'elle touche un bateau du joueur. Si elle rate son coup, c'est à nouveau au joueur de tirer.

Le jeu se poursuit jusqu'à ce qu'un des deux adversaires n'ait plus de bateaux en jeu. Le joueur peut ensuite soit refaire une partie, soit quitter le jeu, en utilisant les boutons à droite de sa grille.

Les options

Plusieurs boutons sont disponibles dans le menu de droite:

Téléchargements

Nous avons modifié l'API-ARV fournie par nos encadrants de façon à ce que l'on puisse utiliser deux FOBs. Voici le patch et la procédure d'installation indispensable pour utiliser notre programme avec le matériel d'ARV.

Ensuite...

Soit: Soit:

Une fois ces modifications effectués, vous pouvez télécharger et utiliser le binaire de notre programme, compilé pour i686.

Retours sur le projet

Dans l'ensemble ce fut pour nous un projet très instructif, qui nous a permis de toucher à beaucoup d'aspects différents de la programmation utilisant la réalité virtuelle. Nous devions résoudre des problèmes aussi bien de "bas niveau" concernant le matériel, que des problèmes de "haut niveau" concernant l'IHM par exemple, la façon dont le joueur intéragira avec l'environnement et les retours d'informations nécessaires.

Le résultat final est à la hauteur de nos espérances. Le jeu fonctionne correctement, les graphismes n'ont pas été développés autant qu'on l'aurait voulu mais ils sont déjà très respectables (ceci est un jugement totalement subjectif).

Si nous devions regretter quelque chose, c'est de ne pas avoir eu assez de temps pour découvrir le matériel et l'API avant de constituer notre cahier des charges, et particulièrement le planning. Nous n'avions pas encore entrevu toutes les possibilités offertes par le matériel avant de proposer notre idée de jeu de bataille navale.
Ensuite, nous avons été vraiment très optimistes en espérant une version utilisable de notre jeu fin novembre. Nous avions très largement sous estimé la difficulté de la prise en main de l'API-ARV, et du temps de travail global nécessaire. Nous avons finallement obtenu une version jouable en janvier, soit avec presque deux mois de retard.