3 Précisions
3.1 Organisation modulaire
Il est demandé une arborescence modulaire pour votre projet. Les trois bibliothèques graphique, réseau et flux d’exécution doivent avoir leur propre répertoire ainsi que les deux exécutables, serveur de jeu et client graphique. Le projet doit pouvoir être compilé par la simple commande make tapée dans le répertoire principal du projet. Le Makefile principal doit aussi implanter la cible clean qui permet de nettoyer l’arborescence des fichiers objets, bibliothèques et exécutables.
Les bibliothèques doivent respecter les paradigmes de généricité et d’encapsulation :
-
les bibliothèques ne doivent contenir que des objets réutilisables et rien de spécifique au projet courant, cependant un maximum de fonctions génériques doivent se trouver dans les bibliothèques ;
- l’utilisation d’une bibliothèque doit être possible sans tenir compte de son implémentation (pas d’autre include nécessaire que celui du .h de la bibliothèque, pas d’utilisation de type ou de structure utilisés par la bibliothèque et non défini dans son propre .h).
Ainsi, dans votre cas, la bibliothèque réseau doit totalement occulter l’utilisation de la bibliothèque socket, la bibliothèque flux d’exécution doit totalement occulter l’utilisation des pthreads et des pthreads_mutex et, enfin, la bibliothèque graphique doit totalement occulter l’utilisation de la bibiliothèque SDL2.
3.2 Structures de données
Les structures de données sont principalement utilisées par le serveur de jeu. Ce dernier doit stocker :
-
l’état du jeu : inscriptions ou jeu en cours ;
- la liste des joueurs : identifiant, pseudo, position, dernières commandes, état, ...
- la liste des murs du labyrinthe en 3D ;
- la liste des tirs, un au maximum par joueur, avec la position de la boule d’énergie et son vecteur vitesse.
En cours de jeu, les 3 dernières structures de données sont fusionnées pour obtenir une liste d’éléments 3D pouvant être des rectangles ou des sphères (globules et boules d’énergie). Pour chaque joueur cette scène est traitée avant que le résultat soit envoyé en UDP au dit client :
-
la scène est centrée sur la position du joueur ;
- une rotation d’axe y est appliquée à la scène selon l’orientation du joueur ;
- les éléments 3D sont triés pour afficher d’abord les éléments occultés ou partiellement occultés (si les éléments sont assez petits, un tri par distance du centre de gravité peut être une bonne approximation) ;
- les éléments sont projetés en 2D puis envoyés en UDP au client.
Le client n’a besoin que de la structure des éléments en 2D pour les récupérer dans le paquet UDP et les afficher.
3.3 Protocoles
Deux protocoles sont à concevoir et implémenter. Un protocole en mode connecté et un protocole en mode non connecté. Vous devez vous concerter avec les autres binômes pour que ces protocoles soient compatibles.
Le protocole en mode connecté va permettre de gérer les phases du jeu. Ce protocole doit fonctionner en mode ASCII avec un code par commande sur quelques caractères suivis d’éventuels arguments (e.g. JOIN <pseudo>).
Ce protocole doit permettre :
-
de s’inscrire à un jeu s’il n’est pas démarré et de recevoir son identifiant de joueur ;
- de démarrer un jeu (uniquement pour les joueurs locaux) ;
- d’envoyer des messages aux autres joueurs ;
- de recevoir des messages des autres joueurs ;
- de recevoir des messages du serveur de jeu (départ ou arrêt du jeu, explosion d’un globule, arrêt du serveur, ...).
Lors de l’implantation de ce protocole un grand soin sera porté à la gestion des connexions et en particulier au traitement propre de la déconnexion non annoncée d’un client ou du serveur.
Le protocole en mode non connecté gère le transfert d’informations durant un jeu :
-
messages réguliers du serveur en diffusion pour solliciter les inscriptions ;
- messages vers le serveur pour envoyer les contrôles du joueur (déplacement, rotation, tir) ;
- messages du serveur vers les clients pour donner la scéne 2D à afficher.
Les deux protocoles sont liés par l’identifiant qui permet de reconnaître le client dans les paquets UDP reçus par le serveur et qui permet au serveur de connaître comment contacter le client.
3.4 Travail à effectuer
Si vous ne voyez pas par où commencer voici quelques étapes que vous pourriez suivre :
-
commencez par faire un schéma des flux d’exécutions qui sont nécessaires au bon fonctionnement des clients et du serveur, profitez-en pour voir quels flux nécessiteront des sémaphores pour garantir l’accès aux variables globales ;
- récupérez le projet fourni, ce projet contient un embryon de la bibliothèque graphique et une démonstration d’utilisation, installez les bibliothèques SDL2 si nécessaire, compilez le programme et exécutez-le ;
- examinez les sources du projet fourni pour vous en inspirer pour la modélisation du labyrinthe, sa manipulation, la projection 2D et l’affichage graphique ;
- concevez la bibliothèque réseau en vous appuyant sur les exemples de fonctions du cours, réalisez un premier exécutable du serveur qui n’implante qu’un simple serveur TCP ;
- concevez la bibliothèque des flux d’exécution, faite en sorte que votre serveur TCP puisse gérer plusieurs clients simultanément ;
- concevez collectivement les protocoles connectés et non connectés ;
- en utilisant les deux protocoles, faites en sorte que votre serveur s’annonce et gère correctement l’inscription de clients, écrivez la partie du client permettant de s’inscrire dès qu’un serveur est disponible ;
- vous pouvez ensuite implanter la partie d’envoi de messages aux autres joueurs en passant par la connexion TCP (le serveur sert de relai pour transmettre les messages à tous les joueurs connectés) ;
- il est conseillé de réaliser d’abord la partie client du jeu, à savoir transmettre les contrôles (déplacement, rotation et tir) au serveur, le serveur ne faisant qu’afficher la position des joueurs en mode texte (les coordonnées et l’angle) ;
- il n’est pas interdit de passer par une phase intermédiaire où le serveur transmet à tous les joueurs une scène 2D statique, vous pouvez ainsi tester l’affichage au niveau des clients ;
- enfin utilisez le code fourni pour calculer la scène 3D réelle puis la scène 2D ;
- terminez par la gestion des messages de contrôle (globule explosé, fin de partie, ...).