C ÉGEP DE S AINTE -F OY – P ROGRAMMATION DE JEUX VIDÉO 1
E XERCICE 04 – R ECYCLAGE D ’ OBJETS
1 Travail à effectuer
Ouvrez le projet de départ fourni avec cet énoncé. Il devrait déjà contenir plusieurs fichiers permettant
de lancer une application fenêtrée qui, une fois cet exercice terminé, vous permettra d’obtenir un
résultat similaire à celui présent dans le dossier exe fourni avec le projet de départ.
Le projet commence avec un mini-jeu d’un vaisseau qui se déplace dans l’espace par vecteur de force.
Vous pouvez observer le code. Vous y trouverez quelques concepts intéressants pour faire des jeux :
• Déplacement d’un acteur par poussée de force.
• Téléportation de cet acteur d’un côté à l’autre de l’écran.
• Projectile créé à la base d’un acteur et projeté par celui-ci (toute tenant compte de la vitesse de
l’acteur).
• Mettre un jeu sur pause (avec la touche p ou start du gamepad)
Prendre connaissance du code de départ de ce projet et bien le comprendre vous aidera pour la suite
des choses dans le cours, mais aussi dans le long terme comme programmeur de jeu vidéo. De
manière plus immédiate, certains termes de la suite de cet énoncé tiendront compte que vous avez
pris connaissance du code.
Cela dit, pour le moment, on a un seul projectile qui se déplace. Relancer le projectile fait seulement
en sorte que le même projectile est ramené au vaisseau et relancé à nouveau.
On va faire quelque chose de plus intéressant et cohérent.
Vous pouvez d’abord compiler et exécuter le projet pour vous assurer qu’il fonctionne correctement.
2 Consignes à respecter
Un peu de musique!
La classe Game possède déjà un attribut de type sf::Music, mais il ne fait rien et aucun fichier de
musique n’est chargée. Vous devez.
I. Charger le fichier de musique (faites-le directement dans Game; comme la musique lit
directement le fichier plutôt qu’un buffer comme les sons, on ne se sert pas du
ContentManager). Utilisez openFromFile.
II. À la fin de Game::init, faites en sorte que la musique puisse jouer en boucle et lancez-la.
III. Si le jeu tombe en pause, mettez la musique en pause et faites-la reprendre avec la reprise du
jeu.
Page 1
Le son des projectiles
Le projet contient une classe Bullet. Prenez quelques instants pour en lire le contenu. Portez une
attention particulière au constructeur de copie et à l’opérateur =. Ce dernier est privé. Pouvez-vous
dire pourquoi?
On veut pouvoir jouer un son lorsqu’un projectile est lancé. Le fait de jouer le son est une
responsabilité de la classe Bullet.
IV. Remarquez l’attribut de type sf::Sound à la classe Bullet.
V. Modifiez le constructeur de copie de la classe Bullet et faites-en sorte d’initialiser le son à
l’aide du SoundBuffer adéquat que vous récupérerez dans la source.
VI. Ajoutez l’instruction requise dans Game::initialize pour affecter le soundbuffer au
projectile créé.
Idéalement, le son devrait être joué dès que le projectile est activé.
VII. Faites la modification pour que le son soit joué dès que le projectile est activé. Assurez-vous
également d’initialiser le temps d’activation à 0 au même moment.
Normalement, rendu ici vous devriez être capable de lancer plusieurs projectiles et ce de façon très
rapprochée. Si vous maintenez le clavier enfoncé, remarquez que le projectile se lance lorsqu’on
relâche la touche. Nous allons ajuster ces comportements.
Recyclage d’objets
Nous souhaitons éviter de créer des projectiles pendant le jeu. Nous devrons donc « prévoir » un
nombre maximal de projectiles pouvant être utilisés … avant le début de la partie.
Cependant, le nombre de projectiles peut varier en fonction de la fréquence de rendu, du temps
imposé entre deux tirs, etc. Les sources de variations sont multiples. Alors comment s’assurer que
l’on disposera de suffisamment de projectiles?
Réponse 1 : Essais et erreurs.
Réponse 2 : On essaie de compter ce dont on estime avoir besoin. On alloue un tableau de projectiles
de la taille calculée et … on espère que ce que sera assez. Ça peut très bien être
l’option retenue à la fin. Elle est valide et peut être utilisée sans gêne.
Réponse 3 : On travaille un peu plus fort au début mais on garde une flexibilité, i.-e. la capacité de
générer « sur le coup » un projectile additionnel si jamais nous en avons besoin. Comment,
en utilisant une structure dynamique (std::list) pour stocker nos projectiles. Si jamais
tous nos projectiles sont utilisés, on peut toujours en créer un nouveau et le placer dans la
liste.
Les cas 2) et 3) sont similaires sur un point : on doit implémenter un pool de projectiles.
- On alloue au départ un nombre fixe de projectiles selon nos prévisions
- Quand on a besoin d’un projectile, on va en chercher un dans le pool qui n’est pas utilisé
(isActive() == false). On l’active (activate(true)) et lui assigne les informations
nécessaires.
- Quand on n’a plus besoin d’un projectile, on le désactive (activate(false)). Il pourra alors
être utilisé quand nous aurons besoin d’un nouveau projectile.
Page 2
Nous allons implémenter le principe de recyclage de projectiles. Vous pouvez choisir la « technique »
que vous souhaitez entre un tableau et une liste de projectiles.
Voici 2 techniques, Il est à noter que l’utilisation d’une liste de Bullet est plus flexible.
Tableau Liste
Déclarez un tableau de 10 Bullet. Déclarez une liste de Bullet.
Dans le init de Game, initialisez les 10 Dans le init de Game, ajoutez 10 projectiles à
projectiles votre liste.
Ajoutez une méthode getAvailableBullet Ajoutez une méthode getAvailableBullet
qui doit retourner le premier Bullet inactif qui doit retourner le premier Bullet inactif
dans le tableau. Assurez-vous d’utiliser des dans la liste. Assurez-vous d’utiliser des
références dès que possible. références dès que possible.
En fonction du masque de saisie, modifiez le code de la méthode update pour lancer un
projectile si le joueur le demande. Je vous suggère de faire une méthode fireBullet dans la
classe PlayerShip qui s’occupera de positionner le projectile et de lui assigner les valeurs
importantes (rotation, poussée).
N’oubliez pas de tenir compte d’un facteur limitant le nombre de tirs à la seconde (recoil)
Modifiez le code la méthode Game::update pour mettre à jour tous les projectiles actifs à
chaque rendu.
Modifiez le code de la méthode Game::draw pour afficher les projectiles actifs uniquement.
VIII. Modifiez le code de la méthode Bullet::update pour faire en sorte de désactiver le projectile
au plus tard 2 secondes après qu’il ait été lancé.
IX. Faites quelques tests pour déterminer le « bon » nombre de projectiles à préallouer au début de
la partie.
Attention
Portez attention à l’utilisation de constantes, au découpage approprié en méthodes, à
l’utilisation de références (&) chaque fois que cela est possible.
Dans les cours qui vont suivre, vous devrez utiliser la technique de « préallocation » pour tous les
types de données dont des instances seront créées à répétition (projectiles, ennemis, bonus,
etc).
Par conséquent, il serait très judicieux de penser à une technique « générale » ( un gestionnaire
d’objets template) qui permettrait de reproduire la gestion pour n’importe quel type). Vous êtes
invités(ées) à explorer cette possibilité.
3 Modalités de remise
Remettez votre projet Visual Studio sur LÉA, dans la section travaux, à l’intérieur d’une archive Zip.
Supprimez tous les dossiers temporaires, à savoir les dossiers .vs, extern, Debug et Release. Ce
Page 3
dernier ne sera pas toujours présent. Assurez-vous aussi que votre projet final ne contient plus aucun
avertissement à la compilation. N’oubliez pas de supprimer les dossiers et fichiers inutiles.
Page 4