EDYCJA: Aby wyjaśnić, jakie dokładnie jest moje pytanie: czy to dobry sposób na obsługę animacji / stanu animacji w silniku gry z myślą o tworzeniu / zarządzaniu treścią? Jakie są wady robienia tego w ten sposób i jaki byłby alternatywny sposób? - Chociaż w mojej odpowiedzi częściowo udzieliłem odpowiedzi w komentarzach, wydaje się, że jest to właściwa droga.
Próbuję obsłużyć animacje w projekcie hobby silnika gier 2D , nie kodując ich na stałe. Twarde kodowanie stanów animacji wydaje mi się powszechnym, ale bardzo dziwnym zjawiskiem.
Trochę tła: pracuję z systemem encji, w którym komponenty są workami danych, a podsystemy działają na nie. Wybrałem system odpytywania do aktualizacji stanów animacji.
Przez stany animacji mam na myśli: „walking_left”, „running_left”, „walking_right”, „strzelanie”, ...
Moim pomysłem na obsługę animacji było zaprojektowanie jej jako modelu opartego na danych . Dane mogą być przechowywane w pliku xml, rdbms, ... I mogą być ładowane na początku gry / poziomu / ... W ten sposób możesz łatwo edytować animacje i przejścia bez konieczności zmiany kodu wszędzie w swoim gra.
Jako przykład stworzyłem wersję XML definicji danych, które miałem na myśli.
Jednym z bardzo ważnych danych byłby po prostu opis animacji . Animacja miałaby unikalny identyfikator (opisową nazwę). Przechowuje identyfikator odwołania do obrazu (z którego korzysta arkusz sprite, ponieważ różne animacje mogą używać różnych arkuszy sprite). Liczba klatek na sekundę, na której uruchomiona zostanie animacja. „Powtórka” określa tutaj, czy animacja powinna być uruchomiona raz czy nieskończenie. Następnie zdefiniowałem listę prostokątów jako ramki.
<animation id='WIZARD_WALK_LEFT'>
<image id='WIZARD_WALKING' />
<fps>50</fps>
<replay>true</replay>
<frames>
<rectangle>
<x>0</x>
<y>0</y>
<width>45</width>
<height>45</height>
</rectangle>
<rectangle>
<x>45</x>
<y>0</y>
<width>45</width>
<height>45</height>
</rectangle>
</frames>
</animation>
Dane animacji byłyby ładowane i przechowywane w puli zasobów animacji, do których odwołują się podmioty gry, które ich używają. Byłby traktowany jako zasób jak obraz, dźwięk, tekstura ...
Drugi fragment danych do zdefiniowania byłby maszyną stanu do obsługi stanów animacji i przejść. Definiuje to każdy stan, w którym może znajdować się jednostka gry, w którym stanie może przejść i co powoduje zmianę tego stanu.
Ta maszyna stanu różni się w zależności od jednostki. Ponieważ ptak może mieć stany „chodzenia” i „latania”, podczas gdy człowiek może mieć stan „chodzenia”. Może być jednak dzielony przez różne byty, ponieważ wielu ludzi prawdopodobnie będzie miało takie same stany (szczególnie, gdy zdefiniujesz kilka pospolitych postaci niezależnych, takich jak potwory itp.). Dodatkowo ork może mieć te same stany co człowiek. Tylko w celu wykazania, że ta definicja stanu może być wspólna, ale tylko przez wybraną grupę podmiotów gry .
<state id='IDLE'>
<event trigger='LEFT_DOWN' goto='MOVING_LEFT' />
<event trigger='RIGHT_DOWN' goto='MOVING_RIGHT' />
</state>
<state id='MOVING_LEFT'>
<event trigger='LEFT_UP' goto='IDLE' />
<event trigger='RIGHT_DOWN' goto='MOVING_RIGHT' />
</state>
<state id='MOVING_RIGHT'>
<event trigger='RIGHT_UP' goto='IDLE' />
<event trigger='LEFT_DOWN' goto='MOVING_LEFT' />
</state>
Stany te mogą być obsługiwane przez system odpytywania . Każda gra zaznacza pobiera bieżący stan podmiotu gry i sprawdza wszystkie wyzwalacze. Jeżeli warunek jest spełniony, zmienia stan jednostki na stan „goto”.
Ostatnią częścią, z którą miałem problemy, było powiązanie danych animacji i stanów animacji z bytem . Wydaje mi się, że najbardziej logiczne jest dodanie wskaźnika do danych maszyny stanów, których używa jednostka, i określenie dla każdego stanu w tej maszynie, jakiej animacji używa.
Oto przykład XML, w jaki sposób zdefiniowałbym zachowanie animacji i graficzną reprezentację niektórych typowych bytów w grze, poprzez odniesienie do stanu animacji i identyfikatora danych animacji. Zauważ, że zarówno „kreator”, jak i „ork” mają te same stany animacji, ale inną animację. Również inna animacja może oznaczać inny arkusz sprite, a nawet inną sekwencję animacji (animacja może być dłuższa lub krótsza).
<entity name="wizard">
<state id="IDLE" animation="WIZARD_IDLE" />
<state id="MOVING_LEFT" animation="WIZARD_WALK_LEFT" />
</entity>
<entity name="orc">
<state id="IDLE" animation="ORC_IDLE" />
<state id="MOVING_LEFT" animation="ORC_WALK_LEFT" />
</entity>
Podczas tworzenia encji dodawałaby listę stanów z danymi maszyny stanu i odniesienie do danych animacji.
W przyszłości używałbym systemu encji do budowania całych encji poprzez definiowanie komponentów w podobnym formacie xml.
-
To właśnie wymyśliłem po kilku badaniach. Miałem jednak problemy z obejściem tego, więc liczyłem na jakieś opinie. Czy jest tu coś, co nie ma sensu, czy jest lepszy sposób, aby sobie z tym poradzić? Wpadłem na pomysł iteracji w ramkach, ale mam problem z pójściem o krok dalej i to jest moja próba zrobienia tego.
Odpowiedzi:
Klipy animacyjne najlepiej opisać zwykłymi, starymi danymi, tak jak zrobiono to w pierwszym fragmencie kodu XML. Możesz to zrobić ręcznie lub wyeksportować do niego z pakietu sztuki. Tak czy inaczej, prawdopodobnie będziesz chciał utworzyć potok, który pobierze go z formatu pośredniego czytelnego dla człowieka, takiego jak XML, i umieści go w czymś ładnym i szybkim do załadowania.
Następnym krokiem jest możliwość renderowania tego. Jeśli używasz wykresu scen, prawdopodobnie oznacza to utworzenie dla niego węzła animacji. Powinieneś być w stanie powiedzieć węzłowi animacji, która animacja jest obecnie odtwarzana i gdzie na osi czasu jest obecnie. Upewnij się, że informacje o obwiedni są dostępne na tym poziomie, abyś mógł łatwo wprowadzić je do swojego systemu uboju.
Teraz będziesz chciał powiązać animację z bytem gry. Zwykle używam modelu opartego na komponentach, więc dla mnie oznacza to komponent AnimState. To jest twoja pośrednia warstwa między grą a renderowaniem. Śledzi, która animacja jest odtwarzana przez jednostkę, tryby rozgrywki (zapętlenie, jeden raz, ping-pong itp.), Czas itp. Może wysyłać zdarzenia takie jak „animover” z powrotem do jednostki i aktualizuje stan animnode w razie potrzeby . AnimStates dla aktywnych podmiotów zostaną zaktualizowane raz na tyknięcie karty SIM, jeśli odtwarzają animację.
Komponent animstate jest prawdopodobnie wystarczający do prostych elementów gry (podstawowe rekwizyty w tle i tym podobne), ale w przypadku bardziej skomplikowanych jednostek będziesz chciał użyć maszyny stanu do zarządzania nim. Najlepiej wyraża się to w języku skryptowym, takim jak Lua lub Python. Stan może mieć kilka bloków funkcjonalnych (onEnter, onExit, onUpdate, onEvent), a także oś czasu określającą określone działania i wyzwalacze, które powinny się zdarzyć w określonych momentach. Prawdopodobnie będziesz mieć jakąś klasę menedżera, która jest odpowiedzialna za aktualizację tych automatów stanów, jeśli jest to właściwe, a także wyzwalanie wywołań zwrotnych na osi czasu, gdy wystąpią. Powinieneś starać się, aby te rzeczy były oparte na zdarzeniach, jak to możliwe, ponieważ każda pisana przez Ciebie aktualizacja OnUpdate będzie kosztem liniowym z liczbą podmiotów. Będziesz także chciał móc określać tagi („atakujący”, „bezczynny”, „ignoreinput” itp.), które są powiązane zarówno z całymi stanami, jak i z określonymi regionami czasowymi stanów. Prawdopodobnie będziesz również potrzebować niektórych procedur obsługi zdarzeń wysokiego poziomu, które dotyczą całego wykresu stanu, a nie tylko określonego stanu.
Postacie „Czujące” prawdopodobnie będą miały także jakąś sztuczną inteligencję. Mam tendencję do tworzenia konkretnego elementu „lokomotorycznego”, który radzi sobie z chodzeniem. Łączy się ze stategraph za pomocą systemu sygnałów i zdarzeń oraz kwerendy o znaczniki stanu i można powiedzieć, aby „chodził do punktu” lub „biegał w określonym kierunku z określoną prędkością”. Komponenty AI wyższego poziomu (takie jak drzewo zachowania itp.) Mogą następnie korzystać z tego interfejsu bez martwienia się o szczegóły.
źródło
Najlepszym systemem animacji opartym na danych, jaki do tej pory widziałem, jest drzewo mieszania . Naprawdę, to cholernie dobrze i może zrobić wszystko, o co tu prosisz. Według AIGameDev.com jest to de facto standard w branży i uważam, że mają rację.
Niestety nie znalazłem dobrego zasobu z szybkim googlowaniem, ale możesz wypróbować to lub tamto, aby uzyskać przegląd. Na stronie AIGameDev.com znajduje się również artykuł na temat płacenia, nie wiem, czy warto założyć konto premium.
źródło