He pasado las últimas 48 horas leyendo sobre los sistemas Object Component, y siento que estoy lo suficientemente preparado para comenzar a implementarlo. Obtuve las clases de objeto y componente base creadas, pero ahora que necesito comenzar a crear los componentes reales, estoy un poco confundido. Cuando pienso en ellos en términos de HealthComponent o algo que básicamente sería una propiedad, tiene mucho sentido. Cuando es algo más general como un componente de Física / Gráficos, me confundo un poco.
Mi clase de Objeto se ve así hasta ahora (si nota algún cambio que deba hacer, avíseme, aún nuevo en esto) ...
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;
};
Ahora, el problema con el que me estoy encontrando es ¿qué pondría la población general en Componentes como Física / Gráficos? Para Ogre (mi motor de renderizado), los Objetos visibles consistirán en múltiples Ogre :: SceneNode (posiblemente múltiples) para adjuntarlos a la escena, Ogre :: Entity (posiblemente múltiples) para mostrar las mallas visibles, y así sucesivamente. ¿Sería mejor simplemente agregar múltiples GraphicComponent al objeto y dejar que cada GraphicComponent maneje un SceneNode / Entity o es la idea de tener uno de cada Componente necesario?
Para Física estoy aún más confundido. Supongo que tal vez cree un RigidBody y realice un seguimiento de mass / interia / etc. Tendría sentido. Pero tengo problemas para pensar cómo poner realmente detalles específicos en un Componente.
Una vez que termine un par de estos componentes "Requeridos", creo que tendrá mucho más sentido. A partir de ahora, aunque todavía estoy un poco perplejo.
fuente
La arquitectura de componentes es una alternativa para evitar las grandes jerarquías que se logran heredando todos los elementos de un mismo nodo, y los problemas de acoplamiento que conduce.
Está mostrando una arquitectura de componentes con componentes "genéricos". Tiene la lógica básica para conectar y desconectar componentes "genéricos". Una arquitectura con componentes genéricos es más difícil de lograr porque no sabes qué componente es. Los beneficios son que este enfoque es extensible.
Se logra una arquitectura de componentes válida con componentes definidos. Con definido quiero decir, la interfaz está definida, no la implementación. Por ejemplo, GameObject puede tener un IPhysicInstance, Transformation, IMesh, IAnimationController. Esto tiene la ventaja de que conoce la interfaz y GameObject sabe cómo manejar cada componente.
Respondiendo al término generalización excesiva
Creo que los conceptos no son claros. Cuando digo componente, no significa que todos los componentes de un objeto de juego deben heredar de una interfaz de componente o algo similar. Sin embargo, este es el enfoque para los componentes genéricos, creo que es el concepto que usted nombra como componente.
La arquitectura de componentes es otra de las arquitecturas que existen para el modelo de objetos en tiempo de ejecución. No es el único y no es el mejor para todos los casos, pero la experiencia ha demostrado que tiene muchos beneficios, como un bajo acoplamiento.
La característica principal que distingue la arquitectura del componente es convertir la relación is-a en has-a. Por ejemplo, una arquitectura de objeto es-a:
En lugar de una arquitectura de objeto has-a (componentes):
También hay arquitecturas centradas en la propiedad:
Por ejemplo, una arquitectura de objeto normal es así:
Objeto1
Object2
Una arquitectura centrada en la propiedad:
Posición
Orientación
¿Es mejor la arquitectura del modelo de objetos? En la perspectiva del rendimiento, es mejor centrado en la propiedad porque es más amigable con la caché.
El componente se refiere a la relación is-a en lugar de has-a. Un componente puede ser una matriz de transformación, un cuaternión, etc. Pero la relación con el objeto del juego es una relación es-a, el objeto del juego no tiene la transformación porque se hereda. El objeto del juego tiene (relación has-a) la transformación. La transformación es entonces un componente.
El objeto del juego es como un centro. si desea un componente que siempre esté ahí, entonces tal vez el componente (como la matriz) debería estar dentro del objeto y no un puntero.
No existe un objeto de juego perfecto para todos los casos, depende del motor, las bibliotecas que utiliza el motor. Tal vez quiero una cámara que no tenga malla. El problema con la arquitectura is-a es que si el objeto del juego tiene una malla, entonces la cámara que hereda del objeto del juego debe tener una malla. Con los componentes, la cámara tiene una transformación, un controlador para el movimiento y todo lo que necesita.
Para obtener más información, el capítulo "14.2. Arquitectura del modelo de objetos en tiempo de ejecución" del libro "Arquitectura del motor de juego" de "Jason Gregory" trata específicamente este tema.
Los diagramas UML se extraen de allí
fuente