2010-09-14 39 views
10

Wyobrażam sobie, że to pytanie lub jego różne wersje są często przekazywane, więc jeśli to, co powiem, jest duplikatem, a odpowiedzi leżą gdzie indziej, proszę poinformuj mnie.Obsługa zdarzeń w komponentowym projekcie silnika gier

Badałem konstrukcje silników gier i natrafiłem na model jednostki opartej na komponentach. Brzmi obiecująco, ale wciąż pracuję nad jego wdrożeniem.

Rozważam system, w którym silnik jest zorganizowany z kilku "podsystemów", które zarządzają pewnym aspektem, jak renderowanie, dźwięk, zdrowie, sztuczna inteligencja itd. Każdy podsystem ma przypisany typ komponentu, taki jak zdrowie komponent dla podsystemu zdrowia. "Istota", na przykład NPC, drzwi, jakiś efekt wizualny lub gracz, składa się z jednego lub więcej elementów, które razem dają podmiotowi funkcjonalność.

Zidentyfikowaliśmy cztery główne kanały przekazywania informacji: komponent może nadawać do wszystkich komponentów w bieżącej encji, komponent może nadawać do swojego podsystemu, podsystem może nadawać do jego składników, a podsystem może nadawać do innych podsystemów.

Na przykład, jeśli użytkownik chciał przenieść swoje znaki, naciśnie klawisz. To naciśnięcie klawisza zostanie pobrane przez podsystem wejściowy, który następnie rozgłasza zdarzenie i zostanie odebrany przez podsystem gracza. Podsystem odtwarzacza wysyła to zdarzenie do wszystkich komponentów odtwarzacza (a więc do elementów, które komponenty tworzą), a te komponenty odtwarzacza będą komunikować się z komponentem pozycji własnej jednostki, aby kontynuować i przenieść.

Wszystko to dla kluczowej prasy wydaje się nieco kręte, i jestem z pewnością otwarta na ulepszenia tej architektury. Ale tak czy inaczej, moje główne pytanie jest nadal aktualne.

Co do samych wydarzeń, zastanawiałem się, gdzie wydarzenie zachowuje się tak, jak we wzorcu odwiedzającego. Znaczenie tego, czego chcę, to to, że jeśli zdarzenie napotka jakiś komponent, który nie obsługuje (jak w przypadku ruchu nie ma nic wspólnego z sztuczną inteligencją lub zdrowiem), zignoruje ten składnik. Jeśli zdarzenie nie znajdzie komponentu, do którego dąży, nie ma to znaczenia.

Wzór gościa prawie działa. Wymagałoby to jednak posiadania funkcji wirtualnych dla każdego typu komponentu (np. VisitHealthComponent, visitPositionComponent, itp.), Nawet jeśli nie ma z nimi nic wspólnego. Mógłbym pozostawić te funkcje puste (więc jeśli natrafiłoby się na te komponenty, byłoby to zignorowane), ale musiałbym dodać kolejną funkcję za każdym razem, gdy dodaję komponent.

Miałem nadzieję, że będę mógł dodać komponent, niekoniecznie dodając rzeczy do innych miejsc i dodać wydarzenie bez naruszania innych rzeczy.

Więc moje dwa pytania:

  1. czy są jakieś ulepszenia mój projekt może umożliwić, pod względem wydajności, elastyczności itp?
  2. Jaki byłby optymalny sposób obsługi zdarzeń?

Odpowiedz

1

Myślałem o używaniu systemów encji dla jednego z moich własnych projektów i przeszedłem przez podobny proces myślowy. Moją pierwszą myślą było wykorzystanie wzorca Observer do radzenia sobie z wydarzeniami - ja też początkowo uważałem, że jest to jakiś wzór gościa, ale zdecydowałem się przeciw niemu z powodów, które wywołujesz.

Moje myśli są takie, że podsystemy dostarczą specyficzny dla podsystemu interfejs publikowania/subskrybowania, a tym samym zależności między podsystemami zostaną rozwiązane w sposób "na wpół" luźny ".Każdy podsystem, który zależy od zdarzeń z innego podsystemu, będzie znał interfejs subskrybenta do tego podsystemu, a zatem może go skutecznie wykorzystać.

Niestety, sposób, w jaki ci subskrybenci uzyskują dostęp do swoich wydawców, wciąż jest w moim umyśle. W tym momencie jestem zwolennikiem pewnego rodzaju dynamicznego tworzenia, w którym tworzony jest każdy podsystem, a następnie druga faza jest używana do rozwiązywania zależności i umieszczenia wszystkich podsystemów w "stanie gotowości".

W każdym razie, jestem bardzo zainteresowany tym, co pracował dla Ciebie i wszelkich problemów, jakie napotykają na swojej projektu :)

1

użyć autobusowym wydarzeniem, aka agregatora zdarzeń. To, czego potrzebujesz, to mechanizm zdarzeń, który nie wymaga sprzężenia między podsystemami, a magistrala zdarzeń to zrobi.

http://martinfowler.com/eaaDev/EventAggregator.html http://stackoverflow.com/questions/2343980/event-aggregator-implementation-sample-best-practices

itp

1

tę architekturę opisaną tutaj http://members.cox.net/jplummer/Writings/Thesis_with_Appendix.pdf Istnieją co najmniej trzy problemy Napotkałem implementację tego w prawdziwym projekcie:

  1. systemy nie są powiadamiane, gdy coś się stanie - wystarczy zapytać o nie - gracz jest martwy? ściana nie jest widoczna? i tak dalej - aby tego uniknąć, można użyć prostej MVC zamiast wzorca obserwatora.
  2. co, jeśli obiekt jest złożony (tzn. Składa się z obiektów)? system przejdzie przez całą hierarchię i zapyta o stan komponentu.
  3. Główną wadą jest to, że architektura ta łączy wszystko razem - np. Dlaczego gracz musi wiedzieć, że naciśnięty został klawisz?

myślę, że odpowiedź jest warstwowe architektury z pobieranej reprezentacji ...

1

Przepraszam mój zły język angielski.

Piszę elastyczny i skalowalny silnik gry 3d Javy oparty na systemie Entity-Component. Skończyłem kilka podstawowych części tego.

Najpierw chcę powiedzieć coś o architekturze ECS, nie zgadzam się, że komponent może komunikować się z innymi komponentami w tej samej jednostce. Komponenty powinny przechowywać tylko dane i systemy je przetwarzać.

W części obsługi zdarzeń, myślę, że podstawowa obsługa wprowadzania nie powinna być zawarta w ECS. Zamiast tego mam system o nazwie Intent System i komponent o nazwie Intent Component, który zawiera wiele intencji. Intencja oznacza, że ​​jednostka chce coś zrobić z bytem. System intentowy przetwarza wszystkie intencje, przetwarzając intencję, nadaje odpowiednie informacje innym systemom lub dodaje do niego inne komponenty.

Piszę również interfejs o nazwie Generator intencji. W lokalnej grze możesz zaimplementować wejście klawiatury lub generator wejściowy myszy, aw grze wieloosobowej możesz zaimplementować generator zamiany sieci. W systemie AI możesz również generować intencje.

Możesz myśleć, że Intent System przetwarza zbyt wiele rzeczy w grze. Ale w rzeczywistości dzieli wiele procesów z innymi systemami. Piszę też system skryptowy. Dla specyficznej specjalnej encji ma komponent skryptowy robiący specjalne rzeczy.

Oryginalnie, kiedy coś rozwijam, zawsze chcę stworzyć wspaniałą architekturę, która zawiera wszystko. Ale czasami tworzenie gier jest bardzo nieefektywne. Inny obiekt gry może mieć zupełnie inne funkcje. ECS jest świetny jako system programowania zorientowany na dane. ale nie możemy uwzględnić w nim wszystkiego, co stanowi kompletną grę.

Nawiasem mówiąc, nasz silnik gry oparty na ECS będzie dostępny w niedalekiej przyszłości, możesz go przeczytać. Jeśli jesteś zainteresowany, zapraszam też do przyłączenia się do nas.