System encji / komponentów i „encje” interfejsu użytkownika

14

Nadal jestem zielony dla systemów encji / komponentów. Uważam, że skoro mam przydatne komponenty do rysowania ikonek (lub arkuszy) i obsługi danych wejściowych (kliknięcia myszą / dotykiem), naturalnie chcę ich ponownie użyć do tworzenia komponentów interfejsu użytkownika (takich jak przyciski, np. Ekran wyboru poziomu).

To wydaje mi się bardzo dziwne. Zawsze rozumiałem byty jako „model gry”, takie jak gracze, wrogowie, ulepszenia itp. Z drugiej strony, z punktu widzenia ponownego użycia kodu, ponowne użycie komponentów do interfejsu użytkownika ma sens.

W jaki sposób (i gdzie) obawy dotyczące interfejsu użytkownika / GUI mieszczą się w systemie encji / komponentu?

(Uwaga: to pytanie jest niezależne od platformy, ponieważ dotyczy wielu platform / języków)

ashes999
źródło
3
Myślę, że wydaje się to logiczne tylko dlatego, że tworzysz grę 2D. Wyobraź sobie, że stworzyłbyś grę 3D (z 2D GUI). Prawie żadna logika renderowania nie mogłaby zostać ponownie użyta, a komponenty 2D GUI w świecie 3D nie miałyby większego sensu. Powinieneś zbudować GUI na systemie komponentów. Podobnie jak w GameplayScreen stwórz świat bytu z komponentami, a jednym z komponentów będzie kamera z „płótnem”, do którego rysuje twój renderer. I to płótno stanie się tłem tego ekranu.
Kikaimaru,
1
@Kikaimaru masz rację na temat 2D. Może zbytnio lubię MVC, ale wydaje się, że jest to połączenie „modelu” (elementów gry) i widoku / kontrolera (elementy interfejsu użytkownika). To działa, jasne, ale czy tak właśnie powinno działać? Czy są lepsze sposoby? Jak robią to inni?
ashes999
@ ashes999 twój komentarz i pierwsze pytanie pochodzą z głębi mojego serca :)
Narek,
@Armen Nigdy nie uzyskałem satysfakcjonującej odpowiedzi na to pytanie.
ashes999
@ ashes999 me to. Wszędzie ludzie mówią, że nie należy mieszać MVC z ECS, ale dlaczego? Czy nie byłoby miło? Inna broń do różnych zadań, prawda?
Narek,

Odpowiedzi:

4

Po użyciu kilku systemów elementów-bytów, zwłaszcza CraftyJS, mniej więcej dostałem odpowiedź na moje pytanie: tak, możesz ponownie użyć komponentów (zwłaszcza ikonek lub obrazów i programów obsługi kliknięć myszką w grach 2D) do GUI.

W większości przypadków masz dostęp tylko do ECS, a nie do bazowych systemów (np. System rysowania). W takim przypadku można używać komponentów, ponieważ nie masz innego wyboru.

Jeśli masz dostęp do bazowego systemu (np. Ruby roguelike z bezpośrednim dostępem do Curses), może się okazać, że rysowanie / renderowanie bezpośrednio w tym systemie jest bardziej efektywne (mniej kodu, mniej kruche, bardziej naturalne) niż używanie zestawu podmioty i komponenty.

ashes999
źródło
Gdzie umieszczasz logikę zaawansowanych elementów interfejsu użytkownika? To znaczy. pasek zdrowia, który musi wiedzieć, kiedy gracz zostanie trafiony i ile go zmniejszyć. Nie wiem, czy potrzebuje konkretnego systemu, skryptu czy czegoś innego ...
Emir Lima,
@EmirLima za coś takiego, umieściłbym większość logiki interfejsu użytkownika w pasku zdrowia (zmieniając rozmiar paska zdrowia), i sprawiłem, że gracz wygeneruje zdarzenie, gdy zostanie trafiony, wskazując, jaka jest nowa / zmieniona wartość zdrowia. (Pasek zdrowia może uchwycić to zdarzenie i odpowiednio zareagować.)
ashes999
Ale czym jest obiekt paska zdrowia w tej architekturze? Czy jest to jednostka z komponentem „paska zdrowia”? Klasa, która dziedziczy po Entity? Normalny obiekt z wywołaniami aktualizacji zakodowanymi na stałe?
Emir Lima,
1
@EmirLima Modelowałbym pasek zdrowia jako byt, a gracz jako byt. Możesz robić wszystko, co ma dla ciebie sens.
ashes999
1

W 2D lub 3D system komponentu bytu (ECS) powinien mieć przynajmniej dostęp do systemu GUI, jeśli nie jest częścią tego samego ECS.

Osobiście nie mieszałbym tych dwóch. Ponowne użycie kodu dla GUI dzieje się naprawdę tylko na najwyższym poziomie. Odpowiadanie na mysz / klawiaturę, renderowanie i tak dalej. Funkcje, które pełnią różne przyciski lub informacje wyświetlane na niektórych listach, nie są tak naprawdę dość ogólne, aby można było z nich korzystać ponownie.

Wyobrażam sobie na przykład, że komponenty jednostek GUI byłyby podobne position, renderi gui. Tam, gdzie komponent GUI określa rodzaj działania, które podejmuje jednostka GUI. Ta akcja będzie jednak wyjątkowa i specyficzna dla kontekstu. Powoduje to, że system, który obsługuje komponenty GUI, jest bardzo duży i zasadniczo zaprojektowany do obsługi każdej z funkcji GUI (załaduj grę, zapisz grę, znajdź serwer itp.). Brzmi bałagan.

Wolałbym zrobić standardowy plik klasy dla każdego „ekranu” GUI. Posiadaj wszystkie funkcje dla tego ekranu w jednym miejscu (z odniesieniami do wspólnej klasy funkcjonalności). Jest o wiele ładniejszy i łatwiejszy w zarządzaniu.

Jednak, jak powiedziałem, ECS powinien mieć dostęp do systemu GUI. Musi być w stanie dostarczyć informacje do GUI na podstawie podmiotów w swoich systemach. Na przykład najechanie kursorem na jednostkę sojuszniczą spowoduje wyświetlenie okna GUI ze wszystkimi informacjami o tej jednostce. Gdy najechanie myszką na jedność wroga wyskoczy okno GUI z ograniczoną ilością informacji. Prawdopodobnie nie chcesz zaprogramować GUI, aby rozpoznać różnicę między nimi, chcesz poprosić jednostkę o wyświetlenie jej informacji.

Tak więc jednostki nadal będą prawdopodobnie miały jakiś komponent GUI, ale będą to jednostki „w grze”, a nie jednostki GUI. Ten komponent użyje zewnętrznego systemu GUI do utworzenia interfejsu GUI.

MichaelHouse
źródło
Wygląda na to, że system, który mam, jest zupełnie inny niż ten, który opisałeś. Mam klasy jednostek, TouchButtonktóre składają się z arkusza sprite i detektora kliknięć dotykiem. W przypadku wyskakującego okienka jednostki prawdopodobnie zaimplementowałbym to jako połączenie komponentu sprite + komponentu detektora myszy. Hmm
ashes999