Informatique Langage C
Résumé de section
-
-
1. Gestion des collisions (projet 4a collision)
Nous allons maintenant nous intéresser aux collisions entre formes (entre un rond et un rectangle), ce qui est à la base de nombreux jeux (pong, space invader, démineur,...). Il n'existe pas de fonctions dédiées à ce problème de collision dans la bibliothèque CSFML qui est une bibliothèque de fonctions permettant d'accéder aux ressources de la machine en langage C ( boucle des messages, carte GPU, joystick, carte son, souris, clavier, fichiers,...) et non une bibliothèque de fonctions dédiées aux jeux vidéos.
Alors comment détecter une collision ? Notre rectangle et notre rond sont connus puisque c'est à la base des animations que nous avons créés.
Eléments du programme connus pour le rectangle
Eléments du programme connus pour le rond
#define L_RECT 50
#define H_RECT 100
#define R_ROND 20
sfVector2f posRect = { 0,0 };//rectangle en haut à gauche
sfVector2f posRond = { 100,100 }; Comment à partir de ces éléments être certain d'une collision entre ces 2 formes ? Le plus simple est de faire le raisonnement inverse : comment être certain qu'il n'y a pas de collision entre forme ? pourquoi plus simple ? parce que ce raisonnement n'impacte qu'un seul test au lieu de plusieurs tests pour chaque cas de figure (collision par en bas, collision par le dessus, collision par les cotés). En effet si le rond est en dessous du rectangle alors on est certain qu'il n'y a pas de collision (bottomRect <= topRond) et on pourrait faire le raisonnement sur les 3 autres cotés (dessus, à droite et à gauche), ce qui est résumé dans les 4 figures ci-dessous.
Donc on peut dire que si les 4 tests (au dessus, au dessous, à droite, à gauche) sont faux alors il n'y a pas de collision et sinon il y a collision.

Donc pour résumer si l'on veut être capable de gérer tous les types de collision, il faut calculer les 4 points définissant chacune des formes puis tester qu'il n'y a pas de collision entre les 2 formes. Comment calculer ces points ? Utiliser les figures ci-dessous pour calculer les 4 points associés à chaque forme.


Mais a-t-on besoin de calculer toutes les collisions ? Dans notre exemple, non puisque la seule collision qui puisse arriver c'est lorsque la balle qui arrive par la droite vient toucher le rectangle qui est à gauche (rightRect <= leftRond), mais si l'on veut gérer aussi les collision avec un rectangle qui serait à droite (jeu de pong) ou un jeu avec des formes placées au milieu (cas du démineur), il est préférable de traiter les 4 cas.
TRAVAIL A FAIRE
- Copier le projet 3_b_texte_son vers le nouveau dossier 4_a_collision
- Calculer les 4 points définissant chacune des formes (topRect, bottomRect, leftRect,rightRect pour le rectangle et topRond, bottomRond, leftRond, rightRond), attention le centre étant en haut à gauche topRect doit être supérieur à bottomRect si on veut que le test de collision soit fonctionnel.
- Ecrire la fonction int detection_collision(sfCircleShape *rond, sfRectangleShape *rect) qui renvoie 1 s'il y a collision et 0 sinon. Tester cette fonction
- Ajouter la gestion de la balle qui doit rebondir à droite mais ne pas rebondir sur les parois à gauche (elle disparait, c'est à dire que son affichage est en dehors de la fenêtre graphique (posRond.x<0). Tester
- Ajouter s'il y a détection de collision avec le rectangle, la balle doit rebondir
- Ajouter la possibilité de réinitialiser le jeu (l'appui sur la touche R vient "resetté" le jeu et replacer le rond à sa position initiale pour relancer la partie.
- Ajouter l'affichage du nombre de balles perdus.
-
2. Travail avec les fonctions (4_b_fonction_base)
Maintenant que nous avons créer notre premier jeu vidéo, voyons ses principales limites : l'ajout d'un deuxième rectangle pour le jeu de pong ou bien pire, l'ajout d'un tableau de rectangle (pour le démineur) va entrainer une difficulté croissante à débugger le programme qui va devenir trés lourd à gérer. La raison en est simple : nous avons un code monolithique dans un seul main et un nombre de données croissantes entrainant des problèmes récurrents de bugs (il y a trop de variables différents par forme graphique).
Nous devons donc organiser notre programme en utilisant des structures de données par élément graphique, créé des fonctions et placer ces fonctions dans des fichiers afin d'avoir un fichier main.c épuré et simple à lire et donc à maintenir et débugger.
Il est donc temps maintenant ( si vous ne l'aviez pas fait précédemment) de terminer les parties 1,2 et 3 et donc de transformer notre projet et de passer d'un seul fichier main.c en plusieurs fichiers (Rectangle.c, Rectangle.h, Rond.c, Rond.h, Texte.c, Texte.h, Son.c, Son.h) et d'ajouter le fichier Collision.c et Collision.h dans lequel vous allez placer la fonction de gestion de collision (et la renommer collision_detection puisque nous avons pris comme règle que le début du nom des fonctions commencent par le nom du fichier qui l'accueille).
TRAVAIL A FAIRE
- copier le projet 3_c_fonction_base. vers 4_b_fonction_base.
- modifier le code pour répondre au cahier des charges et tester.
-