Ostatnie 48 godzin spędziłem na czytaniu na temat systemów typu Object Component i czuję, że jestem wystarczająco gotowy, aby rozpocząć wdrażanie. Utworzyłem podstawowe klasy Object i Component, ale teraz, gdy muszę zacząć tworzyć rzeczywiste komponenty, jestem trochę zdezorientowany. Kiedy myślę o nich w kategoriach HealthComponent lub czegoś, co w zasadzie byłoby po prostu właściwością, ma to sens. Kiedy jest to coś bardziej ogólnego jako komponent fizyki / grafiki, jestem trochę zdezorientowany.
Moja klasa Object wygląda tak do tej pory (jeśli zauważysz jakieś zmiany, które powinienem wprowadzić, daj mi znać, nadal jestem w tym nowy) ...
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;
};
Problem, na który napotykam, polega na tym, co ogólna populacja zastosowałaby w komponentach takich jak fizyka / grafika? W przypadku Ogre (mój silnik renderowania) widoczne Obiekty będą składały się z wielu Ogre :: SceneNode (ewentualnie wielu), aby dołączyć go do sceny, Ogre :: Entity (ewentualnie wielu), aby pokazać widoczne siatki i tak dalej. Czy najlepiej byłoby po prostu dodać do obiektu wiele elementów graficznych i pozwolić każdemu elementowi graficznemu obsługiwać jeden element SceneNode / jednostkę, czy też pomysł posiadania jednego z nich jest potrzebny?
W przypadku fizyki jestem jeszcze bardziej zdezorientowany. Podejrzewam, że może stworzenie RigidBody i śledzenie masy / interia / etc. miałoby sens. Ale mam problem z myśleniem o tym, jak w rzeczywistości umieścić specyfikę w komponencie.
Kiedy skończę kilka z tych „wymaganych” komponentów, myślę, że będzie to o wiele bardziej sensowne. W tej chwili jestem trochę zakłopotany.
źródło
Architektura komponentów jest alternatywą dla uniknięcia dużych hierarchii, które są osiągane podczas dziedziczenia wszystkich elementów z tego samego węzła, oraz problemów z łączeniem, które prowadzi.
Pokazujesz architekturę komponentów z komponentami „ogólnymi”. Masz podstawową logikę do dołączania i odłączania „ogólnych” komponentów. Architektura z ogólnymi komponentami jest trudniejsza do osiągnięcia, ponieważ nie wiesz, który jest komponentem. Korzyścią jest to, że takie podejście jest rozszerzalne.
Prawidłową architekturę komponentów uzyskuje się za pomocą zdefiniowanych komponentów. Mam na myśli zdefiniowany interfejs, a nie implementację. Na przykład GameObject może mieć IPhysicInstance, Transformation, IMesh, IAnimationController. Ma to tę zaletę, że znasz interfejs, a GameObject wie, jak postępować z każdym komponentem.
Odpowiadając na termin nadmiernie uogólniający
Myślę, że koncepcje nie są jasne. Kiedy mówię komponent, nie oznacza to, że wszystkie komponenty obiektu gry muszą dziedziczyć z interfejsu komponentu lub czegoś podobnego. Jednak jest to podejście do Komponentów Ogólnych, myślę, że jest to koncepcja, którą nazywasz komponentem.
Architektura komponentów jest kolejną z architektur istniejących dla modelu obiektów wykonawczych. To nie jedyne i nie najlepsze dla wszystkich przypadków, ale doświadczenie pokazało, że ma wiele zalet, takich jak niskie sprzężenie.
Główną cechą wyróżniającą architekturę komponentów jest konwersja relacji is-a na has-a. Na przykład architektura obiektu to:
Zamiast architektury obiektowej has-a (komponenty):
Istnieją również architektury zorientowane na nieruchomości:
Na przykład normalna architektura obiektowa wygląda następująco:
Object1
Object2
Architektura zorientowana na nieruchomości:
Pozycja
Orientacja
Czy jest lepsza architektura modelu obiektowego? Z punktu widzenia wydajności lepiej jest skoncentrować się na właściwościach, ponieważ jest bardziej przyjazny dla pamięci podręcznej.
Składnik odnosi się do relacji is-a zamiast has-a. Składnikiem może być macierz transformacji, czwartorzęd itp. Ale relacja z obiektem gry jest relacją to -a, obiekt gry nie ma transformacji, ponieważ jest dziedziczony. Obiekt gry ma (relacja ma-a) transformację. Transformacja jest wówczas składnikiem.
Obiekt gry jest jak hub. jeśli chcesz komponent, który zawsze tam jest, to może komponent (podobnie jak matryca) powinien znajdować się wewnątrz obiektu, a nie wskaźnik.
Nie ma idealnego obiektu do gry we wszystkich przypadkach, zależy to od silnika, bibliotek, z których korzysta silnik. Może chcę aparat, który nie ma siatki. Problem z architekturą is polega na tym, że jeśli obiekt gry ma siatkę, to kamera dziedzicząca z obiektu gry musi mieć siatkę. Dzięki komponentom kamera ma transformację, kontroler ruchu i wszystko, czego potrzebujesz.
Aby uzyskać więcej informacji, rozdział „14.2. Architektura modelu obiektów wykonawczych” z książki „Architektura silnika gry” Jason Gregory dotyczy tego tematu.
Stamtąd pobierane są diagramy UML
źródło