Becavin Nicolas
Tschumperle David
Gaillard Boris
ESSI3 VIMM


SuperNBA Basket SouthPark JAM X + Alpha Turbo Z v2.0

 SuperNBA Basket SouthPark JAM X + Alpha Turbo v2.0 (SNBSJX+ATV2 pour les initiés) est le résultat du projet OpenGL proposé par Mr BUFFA dans la filière Synthèse d'images.
Il consiste en un jeu de Basket complet, basé sur les personnages de SouthPark, jouable à deux et en réseau.
Ce jeu est disponible pour PC/Windows et a été développé sous Visual C++. Pour pouvoir jouer à ce superbe jeu révolutionnaire, il suffit de télécharger le fichier suivant: SouthJam.zip
Une fois ce fichier sur votre disque, il suffit de le décompresser dans le répertoire de votre choix (à l'aide de Winzip par exemple).

L'application s'installe alors dans le répertoire que vous avez spécifié. Trois répertoires sont crées dans lesquels vous trouverez surement votre bonheur:

Le programme fonctionne sous Windows 95/98/NT et nécessite un Pentium 133 ou plus muni d'une carte 3D (n'importe quel carte supportant OpenGL).
Cette  application est distribuée en freeware avec les sources en C++. Il ne vous en couteras donc rien, mais si vous decidez de nous envoyer un petit mot par mail, réponse assurée. La première chose à faire est de lancer le jeu :) Pour cela il suffit de choisir l'exécutable correspondant à son matériel (dans un des répertoires décrit ci-dessus) et de double-cliquer dessus. On arrive alors à l'écran suivant:

Sur la droite de la boite de dialogue, on peut choisir la résolution de la fenêtre de jeu et choisir si celle-ci s'affiche en plein écran ou non.
A gauche, on trouve la partie connection au réseau.
La procédure de connection est la suivante:

Le jeu est basé sur un face à face. Il y a deux joueurs sur le terrain, qui tentent de mettre des paniers dans le camp adverse.
Pour cela, chaque joueur sur sa machine dispose des commandes suivantes (les deux machines etant reliées en réseau) :
 
Action
Touche
Avancer
'arrow up'
Reculer
'arrow down'
Tourner a gauche
'arrow left'
Tourner a droite
'arrow right'
Tirer / Sauter
'space'
Prendre la balle a l'adversaire
'c'

l'action Tirer/Sauter permet au joueur qui a la balle de tirer dans le panier, et au joueur qui n'a pas la balle de sauter verticalement pour tenter de prendre la balle en vol.
Un panier rapporte deux points, les deux joueurs sont remis au centre et la balle est donnée au joueur qui a pris le panier.
Lorsque la balle sort en touche, le joueur qui n'avait la balle le dernier la récupère et les joueurs sont remis au milieu.

Rahh, mais puisqu'on vous dit que ce jeu est formidable.. allez , voila des photos pour vous faire saliver...
 

  Le programme a été développé en C++ à l'aide de Visual C++ 5.0. La partie interface graphique utilise les MFC (Micrsoft Fundation Class) et Win32, ce qui limite ma portabilité à Win95/98 ou NT. Cependant, l'architecture est telle qu'il peut être envisagé de réaliser un portage sur une plateforme UNIX sans trop de difficulté.

La structure du programme comporte trois parties distinctes :
 

Le moteur 3d et l'affichage ont été programmés avec la librairie OpenGL. Les différents objets ont été modelisés à la main (comme en 40) à l'aide des différentes primitives OpenGL et GLU: gluCylinder, gluSphere, GL_QUAD ou GL_QUAD_STRIP. Cela permet d'optimiser le nombre de facettes affichées.
Les informations présentées dans cette partie supposent que le lecteur possède une certaine connaissance des principes de base de l'API OpenGL.
Ce moteur 3d comporte les particularités suivantes :
Le principe général du moteur repose sur l'utilisation massive de textures et notamment des textures transparentes. Ainsi, le panier n'est rien d'autre qu'un cône muni d'une texture de filet dont les parties noires sont transparentes.

Le sol est consituée d'une grande face grise constituant le bord du terrain et un ensemble de quatre faces rectangulaires avec une texture représentant les marquages au sol d'un terrain de basket. Les paniers sont constitués d'objets simples. Les panneaux rouges qui font le tour du terrain sont une grande face GL_QUAD_STRIP constituée de 40 faces chainées entre elles pour une meilleure gestion de l'éclairage. De même pour le public.

Le reflet des objets sur le sol est simulé en dessinant chaque objets une deuxième fois mais symétriquement par rapport au plan horizontal, en désactivant le test en Z et en dessinant ces objets de facon transparente.

Chaque objet est définit séparement dans une display list OpenGL et est positionné dans le monde au moment du dessin. Ils sont tous positionnés relativement au centre du repére situé dans un angle du terrain.A l'initialisation, on construit toutes les listes et on charge toutes les textures. Et on positionne les objets au moment du dessin. Par exemple, le terrain faisant 28x15m, le panier de gauche doit être placé en (0,7.5), ceci est fait de la manière suivante au moment du dessin:

glPushMatrix();
glTranslatef(0.0, 0.0, 7.5);
glCallList(PANIER);
glPopMatrix();
                    Le deuxième panier est en (28, 7.5) et seras  dessiné de la manière suivante:
glPushMatrix();
glTranslatef(0.0, 0.0, 7.5);
glRotatef(90, 0.0, 1.0, 0.0);
glCallList(PANIER);
glPopMatrix();
Le ciel est constitué de deux plans proches l'un de l'autre. Le plus haut recoit une texture de nuage et le deuxième recoit une texture similaire mais comportant des zones noires qui seront transparentes. Le mouvement est obtenu par translation dans la matrice GL_TEXTURE:
glMatrixMode(GL_TEXTURE);
glPushMatrix();
glTranslatef(offsetx++, 0.0, offsety++);
glCallList(CIEL);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
Le moteur gère également un système de caméra positionné derrière le joueur. Ce système travaille entièrement dans la matrice MODELVIEW (d'autres solutions peuvent être envisagées en utilisant la matrice GL_PROJECTION). On considére que le centre du repère global (MODELVIEW à l'identité) corresponds à l'oeil de l'utilisateur, le point de visée étant positionné à une distance f (distance focale de la caméra) sur l'axe Oz.Dessiner la scéne reviens alors à placer MODELVIEW à l'identité, à translater de f sur l'axe Oz, à la multiplier par la matrice de transformation de la caméra (résultante des différentes translations et rotations que l'utilisateur à pu effectuer sur cell-ci), à translater de -f sur Oz et à dessiner les objets du monde.
Dans le cas ou la camèra suit le personnage, la matrice de transformation de cell-ci est calculée en fonction de la position et de l'orientation du personnage dans la scène.

Le moteur 3D se contente d'afficher les objets de la scène au bon endroit et avec la bonne orientation, ainsi que la gestion de la camèra. Tous les paramètres (position des joueurs ou de la balle, score, interactions.... ) sont gérés par le module suivant.

Ce module est basé sur la classe BasketGame qui gère le jeu entier. Un objet instance de cette classe est capable de gérer entièrement les mouvemens de deux personnages, d'une balle et de gérer les interactions entre eux. Plusieurs jeux peuvent donc être instanciés en même temps (cela présente un interêt limité mais c'est tout à fait possible).

L'utilisation de ce module passe donc par la création d'un objet BasketGame. Celui-ci contient une méthode run() qui permet de calculer complètement une étape du jeu. Un Timer cadencè à 1/30 s se charge d'appeler cette méthode de BasketGame qui renvoie un objet de type BasketState contenant tous les paramètres du jeu (positions des personnages, scores ......). Exemple d'utilisation:

BasketState bs;
BasketGame bg;

........
SetTimer(1/30); // Appelle OnTimer tous les 1/30 secondes
void OnTimer() {
    bs = bg.run();
}

Les informations de BasketState sont récupérées par le moteur 3D en vue de l'affichage des éléments de la scène.
Les mouvements des personnages sont gérés par des méthodes de BasketGame du type: avanceP1, tourneP1 ou arrêteP1 qui agissent en fait sur les différents paramètres de vitesse et d'accéleration des éléments mobiles. Les mouvements de la balle et des joueurs suivent les lois physiques usuelles. On peut ainsi régler la force de gravité, la vitesse de dribble,l'élasticite ou encore le frottement de la balle sur le sol.

La classe BasketGame s'occupe également de tous l'aspect gestion des collisions Panier/Balle, Joueur/Balle, Panier/Panneau et des paramètres comme le score, les sorties de terrain, les touches, etc ....

Il ne manque alors qu'un élément au programme: le moteur réseau.

Pour des pauvres VIMM comme nous, la gestion du réseau n'a pas été tâche facile. Nous avons utilisé les ressources réseau de Windows fournies par Win32 et les MFC. Le jeu ne pouvant se jouer qu'a deux joueurs, nous avons opté pour la solution suivante :

Chaque ordinateur gère la position de ses joueurs indépendamment (donc un objet BasketGame). Lors d'une action (appui ou relachement d'une touche), la machine du joueur envoit à la machine du joueur adverse le code de la touche concernée permettant ainsi à l'autre joueur de gérer le deuxième personnage. Ce mode de transmission est le plus simple et il ne provoque pas de ralentissement de l'application. C'est un moyen simple et rapide pour résoudre le probleme du jeu en réseau à deux joueurs. Aucune interpolation des positions n'est nécessaire. Cependant il ne représente pas une bonne solution car il est trés sensible aux problèmes de lags et de désynchronisation.

Dans un dévelopement futur, l'idéal serait de mettre en place un serveur qui se charge de gérer la balle et les paramètres de scores et de collisions. Le client se connectera sur ce serveur et se chargera de gérer les déplacements de son personnage et le moteur d'affichage.

L'architecture de ce module est assez classique. On a un serveur de socket positionné sur le port 5600 en mode TCP et en attente de connection. Lorsque qu'une demande de connection est faite, il mets en place un socket entre le client distant et un client local, établissant ainsi la communication entre les dexu applications.
 



Si vous voulez en savoir plus, ecrivez à Nicolas Becavin qui se fera une joie de vous répondre.
Les bourrins associés (c) Mars 1999