Stany animacji oparte na danych

14

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.

użytkownik8363
źródło
1
Wpadłem na podobny pomysł przechowywania danych animacji, chociaż nie rozważałem wyzwalaczy. Oto krótki artykuł, który o nim napisałem, oraz link do projektu XNA, który napisałem, który zużywa XML i zajmuje się animacją. Mam kilka rzeczy, które są różne, na przykład koncepcję zbiorów i sekwencji, ale poza tym myślę, że jesteś na dobrej drodze.
John McDonald,
2
Nie dlatego, że twój projekt jest zły (nie jest, jest bardzo podobny do podobnego systemu, który zbudowałem w przeszłości), ale jakie dokładnie jest twoje pytanie tutaj? Myślę, że to naprawdę może stać się jaśniejsze.
MrCranky,
@ John - Dzięki kolego, przyjrzę się temu później tego wieczoru. @ MrCranky - Cóż, głównie to, co powiedziałeś. Jeśli to jakaś dobra i ewentualnie wskazówki / linki do bardziej uznanych metod. Jestem naprawdę w ciemności, jeśli chodzi o doświadczenie.
user8363
1
Chciałbym wyrazić opinię na temat głębi dostarczanych informacji, ale, aby powtórzyć MrCranky, tak naprawdę nie podążam za pytaniem. Dla mojej osobistej porady (która pojawia się po zbudowaniu tego rodzaju systemu kilka tygodni temu) powiedziałbym, że jesteś na miejscu.
Mike Cluck,
@MikeC To tylko odpowiedź, której potrzebowałem. Przepraszam za to, że nie byłem w stanie wyjaśnić mojego pytania. Może gdybym nie był na miejscu, wyglądałoby to bardziej na pytanie :). Faktem jest, że nie mogłem znaleźć wielu zasobów, które zajmowałyby się stanami animacji i tymi, które go zakodowały, więc tworzenie / zmienianie treści byłoby koszmarem. Więc moje pytanie brzmi: czy to podejście jest właściwe, czy nie? A jeśli powiecie, że tak, to w porządku :).
user8363

Odpowiedzi:

4

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.

Kevin
źródło
1

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.

Laurent Couvidou
źródło
To bardzo dobry zasób, dziękuję. Szukam takich informacji.
user8363
1
Mieszanie animacji nie jest możliwe w przypadku dyskretnych arkuszy sprite, a jedynie w przypadku ciągłej animacji szkieletowej
AlexFoxGill