Jeśli jednostka nie ma wyraźnego „typu” (np. Odtwarzacz) i jest po prostu zbiorem komponentów, w jaki sposób mogę zidentyfikować jednostki, nad którymi moje systemy powinny i nie powinny pracować? Na przykład w grze Pong wiosło i piłka zderzają się z granicami okna. Jednak systemy obsługi kolizji dla każdego będą inne, dlatego system nie powinien obsługiwać jednostek niewłaściwego typu.
void PlayerCollisionSystem::update(std::vector<Entity *> entities) {
typedef std::vector<Entity *>::iterator EIter;
for (EIter i = entities.begin(); i != entities.end(); ++i) {
Entity *player = *i; // How do I verify that the entity is a player?
// Get relevant components.
PositionComponent *position = player->getComponent<PositionComponent>();
VelocityComponent *velocity = player->getComponent<VelocityComponent>();
SpriteComponent *sprite = player->getComponent<SpriteComponent>();
// Detect and handle player collisions using the components.
}
}
Zarówno zawodnik, jak i piłka mają te same istotne typy elementów do obsługi kolizji, ale ich implementacje systemu będą się różnić.
Jeśli mam kontener wszystkich encji w grze, w jaki sposób mogę zidentyfikować określone typy encji bez dziedziczenia Entity
lub uwzględnienia zmiennej członka, takiej jak std::string type
, w którym to przypadku encja nie jest już tylko zbiorem komponentów?
źródło
System jest użyteczny tylko wtedy, gdy jest użyteczny. Jeżeli system, w którym dany podmiot jest „po prostu zbiorem elementów” jest mniej przydatny niż system, w którym jednostka jest głównie jako „zbiór elementów”, a następnie zrobić .
Przestań próbować tworzyć „czyste” systemy i skup się na tworzeniu dobrych , które robią to, czego potrzebujesz. Używaj komponentów, dopóki nie będą już dla ciebie przydatne. Następnie użyj czegoś innego.
Już spędziłeś więcej czasu na myśleniu o tym, niż na to zasługuje.
źródło
Jeśli chcesz nadać jednostkom jawny typ, najprostszym sposobem jest zdefiniowanie zmiennej typu w klasie jednostek. Zachowaj wzór EC tylko tak długo, jak jest to użyteczne.
W przeciwnym razie typ jest sugerowany przez atrybuty komponentu. Na przykład element fizyki miałby atrybut dla urządzeń mobilnych i stacjonarnych. System wie, kiedy zderzą się dwa telefony komórkowe (piłka i wiosło). Podobnie możesz mieć atrybuty określające sposób reakcji systemu kolizji. Zatrzymać obiekt czy go odbić? Patrzenie na atrybuty powinno dać ci wyobrażenie o tym, czym jest byt, ale powinno być nieistotne. Systemy nie powinny wiedzieć, z jakim typem jednostki pracują, powinny otrzymać wystarczającą ilość informacji za pomocą dostarczonych im komponentów.
Wreszcie można dodać dodatkowy komponent, który zawiera typ, ale podobnie jak w przypadku dodawania typu do encji, skończy się pisanie dużej ilości kodu specyficznego dla typu, co pokrzyżuje cel systemu WE.
źródło
Jednostka to zestaw komponentów. Nie można przypisać zgrabnych etykiet do losowego zestawu. Rezygnacja z ograniczeń typu jest ceną za dużą elastyczność.
Oczywiście możesz mieć specjalne (typowane) klasy jednostek, które nakładają ograniczenia na komponenty.
Idealnie komponenty są niezależne. Rozwiązaniem problemu byłoby wywołanie obsługi kolizji w każdym podskładniku, w odpowiedniej kolejności. W rzeczywistych aplikacjach występują współzależności i problemy z porządkowaniem. W takim przypadku potrzebujesz logiki „dyspozytora” w każdej metodzie klasy Entity.
źródło