J'ai passé les 48 dernières heures à lire sur les systèmes de composants d'objet et je sens que je suis assez prêt pour commencer à l'implémenter. J'ai créé les classes d'objet et de composant de base, mais maintenant que je dois commencer à créer les composants réels, je suis un peu confus. Quand je pense à eux en termes de HealthComponent ou quelque chose qui ne serait fondamentalement qu'une propriété, c'est parfaitement logique. Quand c'est quelque chose de plus général en tant que composant physique / graphique, je suis un peu confus.
Ma classe d'objet ressemble à ceci jusqu'à présent (si vous remarquez des changements que je devrais faire s'il vous plaît faites le moi savoir, encore nouveau à cela) ...
typedef unsigned int ID;
class GameObject
{
public:
GameObject(ID id, Ogre::String name = "");
~GameObject();
ID &getID();
Ogre::String &getName();
virtual void update() = 0;
// Component Functions
void addComponent(Component *component);
void removeComponent(Ogre::String familyName);
template<typename T>
T* getComponent(Ogre::String familyName)
{
return dynamic_cast<T*>(m_components[familyName]);
}
protected:
// Properties
ID m_ID;
Ogre::String m_Name;
float m_flVelocity;
Ogre::Vector3 m_vecPosition;
// Components
std::map<std::string,Component*> m_components;
std::map<std::string,Component*>::iterator m_componentItr;
};
Maintenant, le problème que je rencontre est ce que la population générale mettrait dans des composants tels que la physique / graphique? Pour Ogre (mon moteur de rendu), les objets visibles seront constitués de plusieurs Ogre :: SceneNode (éventuellement plusieurs) pour le joindre à la scène, Ogre :: Entity (éventuellement plusieurs) pour afficher les maillages visibles, etc. Serait-il préférable d'ajouter simplement plusieurs GraphicComponent à l'objet et de laisser chaque GraphicComponent gérer un SceneNode / Entity ou l'idée d'avoir un de chaque composant est-elle nécessaire?
Pour la physique, je suis encore plus confus. Je suppose que peut-être créer un RigidBody et garder une trace de la masse / interia / etc. serait logique. Mais j'ai du mal à penser à comment réellement mettre des détails dans un composant.
Une fois que j'aurai fait quelques-uns de ces composants "requis", je pense que cela aura beaucoup plus de sens. En ce moment même si je suis encore un peu perplexe.
la source
L'architecture des composants est une alternative pour éviter les grandes hiérarchies obtenues héritant de tous les éléments d'un même noeud, et les problèmes de couplage qui en découlent.
Vous montrez une architecture de composants avec des composants "génériques". Vous avez la logique de base pour attacher et détacher des composants "génériques". Une architecture avec des composants génériques est plus difficile à réaliser car vous ne savez pas de quel composant il s'agit. Les avantages sont que cette approche est extensible.
Une architecture de composant valide est obtenue avec des composants définis. Avec défini, je veux dire, l'interface est définie, pas la mise en œuvre. Par exemple, GameObject peut avoir une IPhysicInstance, Transformation, IMesh, IAnimationController. Cela a l'avantage de connaître l'interface et le GameObject sait comment gérer chaque composant.
Répondre au terme de généralisation excessive
Je pense que les concepts ne sont pas clairs. Quand je dis composant, cela ne signifie pas que tous les composants d'un objet de jeu doivent hériter d'une interface de composant ou quelque chose de similaire. Cependant, c'est l'approche pour les composants génériques, je pense que c'est le concept que vous nommez en tant que composant.
L'architecture des composants est une autre des architectures qui existent pour le modèle d'objet d'exécution. Ce n'est pas le seul et ce n'est pas le meilleur pour tous les cas, mais l'expérience a démontré que cela présente de nombreux avantages, comme un faible couplage.
La principale caractéristique qui distingue l'architecture des composants est de convertir la relation is-a en has-a. Par exemple, une architecture d'objet est-a:
Au lieu d'une architecture d'objet has-a (composants):
Il existe également des architectures centrées sur la propriété:
Par exemple, une architecture d'objet normale est comme ceci:
Object1
Object2
Une architecture centrée sur la propriété:
Position
Orientation
C'est mieux l'architecture du modèle objet? Du point de vue des performances, il vaut mieux la propriété centrée car elle est plus compatible avec le cache.
Le composant fait référence à la relation is-a au lieu de has-a. Un composant peut être une matrice de transformation, un quaternion, etc. Mais la relation avec l'objet-jeu est une relation is-a, l'objet-jeu n'a pas la transformation car il est hérité. L'objet-jeu a (relation has-a) la transformation. La transformation est alors un composant.
L'objet de jeu est comme un hub. si vous voulez un composant qui est toujours là, alors peut-être que le composant (comme la matrice) devrait être à l'intérieur de l'objet et non un pointeur.
Il n'y a pas d'objet de jeu parfait dans tous les cas, cela dépend du moteur, des bibliothèques que le moteur utilise. Peut-être que je veux un appareil photo sans maillage. Le problème avec l'architecture is-a est que si l'objet de jeu a un maillage, la caméra qui hérite de l'objet de jeu doit avoir un maillage. Avec des composants, la caméra a une transformation, un contrôleur pour le mouvement et tout ce dont vous avez besoin.
Pour plus d'informations, le chapitre "14.2. Runtime Object Model Architecture" du livre "Game Engine Architecture" de "Jason Gregory" traite spécifiquement de ce sujet.
Les diagrammes UML en sont extraits
la source