Pour ce projet vous allez travailler avec une autre personne. Vous devez bien sûr travailler ensemble : concevoir le programme ensemble, le taper et le mettre au point ensemble sur l'ordinateur. Il n'est pas question que certains fassent le travail, et que d'autres y ajoutent leur nom ! Vous ne devrez rendre qu'un ensemble de rapports en indiquant vos noms.
Il faudra rendre un rapport et un programme : c'est-à-dire plusieurs fichiers que vous regrouperez dans une archive ZIP ou RAR ou TGZ; Vous devrez me l'envoyer par mail à l'adresse suivante : pa@lri.fr N'envoyez qu'un et un seul mail par binôme.
On se propose de réaliser le jeu de type Kill them all en beaucoup plus simple, avec un affichage 3D lui aussi simplifié.
La machine anime des personnages de type gardien dont le but est de protéger un trésor caché dans une pièce du labyrinthe, que vous, le chasseur, essayez de prendre.
Le chasseur se déplace dans le labyrinthe dans une direction qui est indiquée par la souris et/ou le clavier, c'est le joueur humain qui contrôle complètement le chasseur. Par contre, les gardiens sont des incarnations de la machine : ils sont animés par une sorte d'instinct artificiel qui les poussent a attaquer le chasseur.
Chaque personnage possède un capital initial de survie qui est décrémenté à chaque fois qu'il subit une attaque de l'un de ses adversaires. Ce capital est incrémenté quand le personnage reste un certain temps sans subir de blessure (ou tout autre critère comme par exemple trouver des réserves de santé sous forme de caisses de survie). Le capital initial de chaque type de personnage (gardiens, chasseur) et le temps de récupération devront être des paramètres du programme.
Les gardiens ont deux états de fonctionnement :
Les critère qui décide de l'état dans lequel est un gardien est simple : un gardien qui voit le chasseur passe en mode attaque, sinon il passe en mode patrouille. Un gardien voit le chasseur quand aucun obstacle se trouve entre ce gardien et le chasseur.
Réciproquement, le chasseur peut attaquer les gardiens, il partage avec les gardiens la caractéristique d'avoir une précision de tir variable avec sont état de santé. Le coefficient n'est pas le même que pour un gardien car le tir du chasseur est dirigé par un humain (et est donc bien moins précis que ce que peut faire la machine).
Le constructeur de la classe Labyrinthe servira à initialiser un labyrinthe selon la représentation interne du programme de jeu à partir d'une représentation textuelle du labyrinthe (à l'aide des caractères + - |).
Conceptuellement le labyrinthe est en 2D, c'est l'affichage graphique qui va
le rendre en 3D, vos personnages évoluent dans un plan où les murs des pièces
(ou des couloirs qui ne sont que des pièces particulières) sont des lignes
droites horizontales ou verticales. Le labyrinthe est fermé, et possède
deux pièces particulières :
Pour meubler le labyrinthe, on pourra y placer des caisses qui
empêchent le passage. Des affiches (images gif ou jpg) pourront aussi être
montrées sur les murs.
On repérera les positions (initiales) du chasseur, des gardiens, du trésor et
des caisses dans le labyrinthe à l'aide de lettres spécifiques:
Pour que votre code soit lisible vous mettrez un gros commentaire au début de chaque fichier indiquant à quoi servent les classes qui s'y trouvent, comment elles s'articulent pour constituer le module et à quoi sert ce module. Vous mettrez aussi un petit commentaire en tête de chaque méthode indiquant ce qu'elle fait, la signification de chacun de ses arguments, et celle de la valeur de retour. Enfin, mettez un petit commentaire indiquant ce que représente chaque champ de donnée de vos classes. Veillez aussi à respecter les conventions de nommage qui vous ont été indiquées dans le cours.
C'est à vous de concevoir l'architecture de votre programme de façon à ce qu'il ait toutes les qualités exigées d'un bon logiciel : simplicité, concision, clarté, etc.
Entre autres, commencez par identifier les objets impliqués dans le programme, indiquez comment ces objets s'articulent entre eux pour faire ce qu'on vous demande. Parallèlement, commencez à énumérer les caractéristiques de ces objets : attributs puis méthodes, pour identifier leur classe. Ensuite, regardez les relations entre ces classes, peut être partagent-elles des caractéristiques ? Vous pourrez implémenter ces relations avec la dérivation ou l'utilisation.
Cette archive
contient aussi toutes les textures (fichiers .jpg) et le modèle de gardien
(garde.md2).
Bien entendu, il ne faut pas modifier ne serait-ce que d'un caractère
le contenu de ces fichiers d'entête...
Sauf bien sur Labyrinthe.h et Labyrinthe.cc de vous devez
récrire : votre classe Labyrinthe (dérivée de Environnement)
doit posséder un constructeur qui prend un argument de type char* qui
est le nom du fichier définissant le labyrinthe.
La constante Environnement::scale est un facteur d'échelle permettant de convertir des coordonnées flottantes de personnages en coordonnées entières dans la carte. Cette conversion se passe de la façon suivante: (par exemple)
Mover* m; int i = (int) (m -> _x / Environnement::scale); int j = (int) (m -> _y / Environnement::scale);
Rien de tel qu'un exemple pour comprendre comment utiliser du code que vous
n'avez pas écrit vous même. Téléchargez l'archive LabyrintheProto.tgz
(voir plus haut):
La classe Mover (et donc par conséquence ses dérivées Gardien et Chasseur) permet l'affichage d'un projectile (boule de feu) qui nécessite l'inclusion du fichier FireBall.h et une méthode virtuelle :
dont un exemple est donné dans Chasseur.h. Cette fonction est appelée automatiquement quand on a initialisé un tir (voir la méthode fire du chasseur). Elle retourne vrai si le déplacement est accepté et faux s'il y a une collision. En cas de collision, la boule explosera automatiquement.