Jest to kontynuacja tego pytania, na które odpowiedziałem, ale to dotyczy bardziej szczegółowego tematu.
Ta odpowiedź pomogła mi zrozumieć Entity Systems nawet lepiej niż ten artykuł.
Przeczytałem (tak,) artykuł o systemach Entity Systems i powiedział mi, co następuje:
Encje to tylko identyfikator i tablica komponentów (artykuły mówią, że przechowywanie encji w komponentach nie jest dobrym sposobem robienia rzeczy, ale nie stanowi alternatywy).
Składniki to fragmenty danych, które wskazują, co można zrobić z określonym bytem.
Systemy są „metodami”, które manipulują danymi na bytach.
Wydaje się to bardzo praktyczne w wielu sytuacjach, ale niepokoi mnie to, że komponenty są tylko klasami danych. Na przykład, jak mogę zaimplementować moją klasę Vector2D (Pozycja) w systemie Entity?
Klasa Vector2D przechowuje współrzędne data: xiy, ale ma także metody , które są kluczowe dla jej użyteczności i odróżniają klasę od tablicy tylko dwóch elementów. Przykładowe metody są: add()
, rotate(point, r, angle)
, substract()
, normalize()
i wszystkie inne standardowe, użyteczny i nie jest to absolutnie konieczne metody, które pozycje (które są instancje klasy Vector2D) powinna posiadać.
Gdyby komponent był tylko posiadaczem danych, nie byłby w stanie mieć tych metod!
Jednym z rozwiązań, które prawdopodobnie mogłoby się pojawić, byłoby wdrożenie ich w systemach, ale wydaje się to bardzo sprzeczne z intuicją. Te metody to rzeczy, które chcę teraz wykonać, aby były kompletne i gotowe do użycia. Nie chcę czekać na MovementSystem
przeczytanie jakiegoś drogiego zestawu komunikatów, które nakazują mu wykonać obliczenia dotyczące pozycji bytu!
I artykuł bardzo wyraźnie stwierdza, że tylko systemy powinny mieć jakąkolwiek funkcjonalność, a jedynym wyjaśnieniem tego, co mogłem znaleźć, było „unikanie OOP”. Przede wszystkim nie rozumiem, dlaczego powinienem powstrzymywać się od stosowania metod w jednostkach i komponentach. Narzut pamięci jest praktycznie taki sam, a w połączeniu z systemami powinny być bardzo łatwe do wdrożenia i łączenia w interesujący sposób. Na przykład systemy mogą zapewniać podstawową logikę tylko jednostkom / komponentom, które same znają implementację. Jeśli mnie o to zapytasz - to w zasadzie pobieranie korzyści zarówno z ES, jak i OOP, czego według autora artykułu nie można zrobić, ale wydaje mi się, że to dobra praktyka.
Pomyśl o tym w ten sposób; w grze istnieje wiele różnych typów obiektów do rysowania. Plain Old obrazy, animacje ( update()
, getCurrentFrame()
itp), kombinacje tych typów pierwotnych, a wszystkie z nich może po prostu stanowić draw()
metodę do systemu render, który wtedy nie trzeba się martwić o jak sprite podmiotu jest realizowany tylko na temat interfejsu (rysowanie) i pozycji. A potem potrzebowałbym tylko systemu animacji, który nazwałby metody specyficzne dla animacji, które nie mają nic wspólnego z renderowaniem.
I jeszcze jedna rzecz ... Czy naprawdę istnieje alternatywa dla tablic, jeśli chodzi o przechowywanie komponentów? Nie widzę innego miejsca do przechowywania komponentów niż tablice wewnątrz klasy Entity ...
Być może jest to lepsze podejście: przechowuj komponenty jako proste właściwości jednostek. Na przykład element pozycji byłby przyklejony entity.position
.
Tylko inny sposób byłoby mieć jakąś dziwną tabeli odnośników wewnątrz systemów, która odwołuje różne podmioty. Ale wydaje się to bardzo nieefektywne i bardziej skomplikowane do opracowania niż zwykłe przechowywanie komponentów w bycie.