- Amir,
Bonsoir
J’ai récemment débuté un projet de moteur de jeu 2D utilisant la librairie SFML dans l’optique de m’améliorer dans ce langage et dans la conception 2D. Je n’ai pas de réels soucis techniques pour le moment mais, au fil de l’avancement du projet je me rends compte que je ne sais pas vraiment comment je devrais organiser mon projet et hiérarchiser mes différentes classes.
Plus précisément, j’ai l’infime conviction de bafouer moult règles de la programmation orientée objet et si je souhaite que mon moteur soit réutilisable et un minimum décent cela ne sera pas tenable sur le long terme.
Voici donc les questions conceptuelles (mais pas seulement) que je me pose :
1) J’ai conçu une classe TileMap, qui hérite d’une classe Map. Au début, j’étais parti sur une utilisation d’un std::vector à 2 dimensions, néanmoins j’ai lu dans un livre qu’il était préférable de travailler en interne sur un objet matriciel à une dimension et ainsi linéariser le tableau 2D.
J’ai alors une architecture proche de :
class TileMap : public Map{
public:
TileMap(SpriteSheet const& spriteSheet, std::vector<std::vector<int>> mapVector); // L'un des constructeur de ma classe TileMap
private:
SpriteSheet spriteSheet_{};
Matrix mapMatrix_ {};
};
Puis lors dans le corps de ce constructeur je remplis ma matrice avec les éléments du std::vector passé en paramètre.
Je me demande si il est logique de procéder ainsi ou si il serait préférable de forcer l’utilisateur à utiliser lui-même un objet de type Matrix lors de l’utilisation de la classe TileMap ? Le principe de Demeter ne le permettrait à priori pas ?
2) Toujours dans cette classe TileMap, j’ai rencontré la problématique suivante : où la logique (j’entends ce qui touche aux collisions de tuiles) devrait-elle se trouver ? Qu’est-ce qui devrait gérer tout cela ?
Pour le moment ma class TileMap propose de nombreuses méthodes telles que
makeSolid(int value);
qui prend en argument un entier censé représenter la valeur de la tile dans la TileMap et qui ajoute cet entier à un tableau qui liste toutes les tiles solides. Une telle méthode a-t-elle sa place ici ? J’ai de plus des méthodes qui me semblent pas mal alourdir ma classe telles que isSolid(Vector2u const& index) qui renvoie un bool si la position en indice (en terme de tiles, (1,1) étant la toute première à l’écran) est solide.
2) - Suite - J’ai une fonction dans un fichier totalement à part nommé collision.hpp
template<typename T>
bool collisionSolid(T const& A, TileMap const& map);
Qui grossièrement me dit si mon objet de type T touche une tuile solide.
De nombreuses autres fonctions sont présentes dans ce fichier comme des tests de collision avec les bordures d’un objet Window en argument, ou des tests de collisions avec la méthode des boites englobantes.
Est-ce la bonne façon de procéder ?
3) (Dernière question promis ) Je me demande si il serait judicieux de concevoir une classe abstraite PhysicEntity avec en attributs une masse, une vitesse etc, et dont hériteront les principaux objets sur lesquels je pourrai tester des collisions et appliquer des lois physiques plus tard avec une autre classe Physic. Cette idée serait-t-elle viable sur le long terme ?
Je me demande aussi si il est logique qu’un Sprite hérite directement de PhysicEntity ?
De plus, je pourrais dans une telle situation songer à modifier mes fonctions de tests de collision, par exemple :
bool collisionSolid(PhysicEntity* A, TileMap const& map);
Voilà voilà, désolé pour la longueur du message et un grand merci à ceux qui m’auront lu jusqu’au bout,
Bonne soirée à tous/toutes