Bonjours à tous,
Je suis en train d'apprendre le C++, et pour m'entraîner j'essaie de reproduire des petits jeux qui existent déjà. Étant encore plutôt débutant, je ne suis pas toujours sûr de concevoir ces jeux de la meilleure manière, et c'est pour ça que je sollicite votre aide.
Voici le contexte actuel : je suis en train de coder un Pac-Man (pas besoin de connaître le jeu pour comprendre le problème) en essayant d'être le plus proche possible de l'original. Mon premier problème est arrivé assez rapidement :
1.
J'ai tout d'abord créé une classe Pac-Man et une classe Map. J'ai donc les objets pacMan et map qui sont mis à jours et dessinés à chaque boucle (le code ne provient pas directement de mon projet, c'est juste pour donner une image) :
1 2 3 4 5 6 7 8 9 | //boucle principale //mise à jour map.update(); pacMan.update(); // affichage des entités window.draw(map); window.draw(pacMan); |
Map contient les tuiles, c'est-à-dire les murs solides et les dots (les points que Pac-Man doit manger) dans un tableau. Chaque fois que Pac-Man passe sur un dot, le dot disparaît et le score augmente. C'est là que je suis confus : où et comment faut-il gérer la disparition et l'augmentation du score ? Dans la classe Map ? Dans la classe PacMan ? Ou dans la boucle principale ?
J'ai d'abord pensé à faire passer par paramètre la position de PacMan et le score :
1 | map.update(pacMan.position(), score); |
Sauf que PacMan a besoin de connaître les murs lorsqu'il se déplace, donc il faudrait aussi faire :
1 | pacMan.update(map.tiles()); |
Ou alors je pourrais aussi faire passer ces informations par le constructeurs. Mais cela m'a paru un peu absurde de passer toujours plein de paramètres dans les méthodes updates ou dans le constructeur. Est-ce une bonne idée ?
Pour finir, j'ai décidé de mettre ces objets (tuiles, score…) dans une autre classe en tant que membres statiques, afin qu'ils soit utilisables partout dans le projet. Mais j'ai souvent entendu qu'utiliser des variables globales était une mauvaise pratique. Pourtant, je trouve ça bien agréable à utiliser. Devrais-je éviter ? Et si non, comment devrait-je appeler cette classe ?
2.
Viennent en suite les quatre fantômes. Au début je me suis dit que je devrais créer une classe Ghost, puis quatre autres classes qui héritent de cette dernière (car les fantômes agissent tous différemment). Cependant, j'ai pu lire qu'il valait souvent mieux utiliser une seule classes avec plusieurs composants. Ainsi, je définie mes quatre fantômes en tant que Ghost, en faisant passer leur type par le constructeur (du genre Ghost blinky(RED), Ghost pinky(PINK)).
Maintenant, lors de la méthode update des Ghosts, on a besoin de connaître la position de Pac-Man. Certains fantômes ont même besoin de la direction de Pac-Man. Du coup ici, la question est la même qu'avant : comment ces Ghosts doivent-il accéder à la position/direction de Pac-Man ? En les faisant passer par paramètre (dans le constructeur ou update()) ? Ou en les mettant en tant que variables globales à nouveau ? Car ne serait-ce pas inutile d'obtenir la direction de Pac-Man pour un fantôme qui n'en a pas besoin ?
Cette fois-ci, mettre la position/direction de Pac-Man en tant que variables globales m'a paru plutôt une mauvaise idée. Donc je les fais passer en paramètres (au constructeur).
Un autre problème, c'est que le fantôme bleu doit connaître la position du fantôme rouge. Du coup je devrais aussi passer la position du fantôme rouge par paramètre pour tous les fantômes ? Cela aussi me semble absurde. Devrais-je faire plusieurs fonction updates avec à chaque fois des paramètres différents ? Ou finalement opter pour créer quatre classes héritant de Ghost (qui seront donc assez minuscules) ?
Voilà
Je suis donc confus dans la manière de modifier un élément provenant d'une autre entité. J'espère donc que vous serez capables de m'indiquer quelques astuces afin d'avoir un code en ordre, propre et "moderne".
Je vous remercie d'avance.