Stati di animazione basati sui dati


14

EDIT: Per chiarire qual è esattamente la mia domanda: è un buon modo per gestire le animazioni / lo stato delle animazioni in un motore di gioco con un occhio alla creazione / gestione dei contenuti? Quali sono i difetti nel farlo in questo modo e quale sarebbe un modo alternativo per farlo? - Sebbene la mia risposta abbia parzialmente risposto nei commenti, poiché sembra essere la strada da percorrere.

Sto cercando di gestire le animazioni in un progetto di hobby del motore di gioco 2D , senza codificarle. Gli stati di animazione con codifica rigida mi sembrano un fenomeno comune ma molto strano.

Un po 'di storia: sto lavorando con un sistema di entità in cui i componenti sono sacchi di dati e i sottosistemi agiscono su di essi. Ho scelto di utilizzare un sistema di polling per aggiornare gli stati di animazione.

Con stati di animazione intendo: "walking_left", "running_left", "walking_right", "shooting", ...

La mia idea di gestire le animazioni era progettarla come un modello basato sui dati . I dati potrebbero essere memorizzati in un file XML, un rdbms, ... E potrebbero essere caricati all'inizio di un gioco / livello / ... In questo modo puoi facilmente modificare animazioni e transizioni senza dover cambiare il codice ovunque nel tuo gioco.

Ad esempio, ho realizzato una bozza XML delle definizioni dei dati che avevo in mente.

Un dato molto importante sarebbe semplicemente la descrizione di un'animazione . Un'animazione avrebbe un ID univoco (un nome descrittivo). Conterrebbe un ID di riferimento a un'immagine (il foglio sprite che utilizza, poiché animazioni diverse possono utilizzare fogli sprite diversi). I fotogrammi al secondo su cui eseguire l'animazione. Il "replay" qui definisce se un'animazione debba essere eseguita una volta o all'infinito. Quindi ho definito un elenco di rettangoli come cornici.

<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>

I dati di animazione verrebbero caricati e conservati in un pool di risorse di animazione e referenziati dalle entità di gioco che li utilizzano. Sarebbe trattato come una risorsa come un'immagine, un suono, una trama, ...

Il secondo pezzo di dati da definire sarebbe una macchina a stati per gestire stati e transizioni di animazione . Questo definisce ogni stato in cui può trovarsi un'entità di gioco, in cui afferma che può passare e che cosa fa scattare quel cambiamento di stato.

Questa macchina a stati differirebbe da un'entità all'altra. Perché un uccello potrebbe avere stati "camminare" e "volare" mentre un essere umano avrebbe solo lo stato "camminare". Tuttavia potrebbe essere condiviso da entità diverse perché più umani probabilmente avranno gli stessi stati (specialmente quando si definiscono alcuni NPC comuni come mostri, ecc.). Inoltre un orco potrebbe avere gli stessi stati di un essere umano. Giusto per dimostrare che questa definizione di stato potrebbe essere condivisa, ma solo da un gruppo selezionato di entità di gioco .

<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>

Questi stati possono essere gestiti da un sistema di polling . Ogni spunta di gioco prende lo stato corrente di un'entità di gioco e controlla tutti i trigger. Se viene soddisfatta una condizione, cambia lo stato dell'entità nello stato "goto".

L'ultima parte con cui stavo lottando era come legare i dati e gli stati di animazione a un'entità . L'approccio più logico mi è sembrato di aggiungere un puntatore ai dati della macchina a stati che un'entità utilizza e di definire per ogni stato in quella macchina quale animazione utilizza.

Ecco un esempio xml di come definirei il comportamento dell'animazione e la rappresentazione grafica di alcune entità comuni in un gioco, rivolgendomi allo stato e all'ID dei dati di animazione. Si noti che sia "procedura guidata" che "orco" hanno gli stessi stati di animazione ma un'animazione diversa. Inoltre, un'animazione diversa potrebbe significare un foglio sprite diverso o anche una diversa sequenza di animazioni (un'animazione potrebbe essere più lunga o più corta).

<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>

Quando viene creata l'entità, viene aggiunto un elenco di stati con dati della macchina a stati e un riferimento ai dati di animazione.

In futuro userò il sistema di entità per costruire intere entità definendo i componenti in un formato XML simile.

-

Questo è quello che ho escogitato dopo alcune ricerche. Tuttavia ho avuto qualche problema a pensarci bene, quindi speravo in un feedback. C'è qualcosa qui che non ha senso o c'è un modo migliore per gestire queste cose? Ho afferrato l'idea di iterare attraverso i frame, ma ho difficoltà a fare un passo avanti e questo è il mio tentativo di farlo.


1
Ho avuto un'idea simile per l'archiviazione dei dati di animazione, anche se non ho considerato i trigger. Ecco un breve articolo che ho scritto a riguardo e un link a un progetto XNA che ho scritto che consuma l'XML e gestisce il lato dell'animazione delle cose. Ho alcune cose che sono diverse, come il concetto di Set e Sequenze, ma a parte questo, penso che tu sia sulla buona strada.
John McDonald,

2
Non che il tuo design sia cattivo (non lo è, è molto simile a un sistema simile che ho costruito in passato), ma qual è esattamente la tua domanda qui? Penso che potrebbe davvero essere più chiaro.
MrCranky,

@ John - Grazie amico, lo guarderò più tardi stasera. @ MrCranky - Beh, principalmente proprio quello che hai detto. Se è buono e forse suggerimenti / collegamenti a metodi più consolidati. Sono davvero al buio qui per esperienza.
user8363

1
Vorrei dare a questo un voto per la profondità delle informazioni fornite ma, per far eco a MrCranky, non sto davvero seguendo quale sia la domanda. Per il mio consiglio personale (che nasce dalla creazione di questo tipo di sistema un paio di settimane fa) direi che sei perfetto.
Mike Cluck,

@MikeC Questa è solo la risposta di cui avevo bisogno. Mi scuso per il fatto che non sono stato in grado di essere più chiaro sulla mia domanda. Forse se non ci fossi a posto sarebbe più una domanda :). Il fatto è che non sono riuscito a trovare molte risorse che si occupavano degli stati di animazione e di quelli che lo codificavano in modo rigido, quindi la creazione / modifica dei contenuti sarebbe un incubo. Quindi la mia domanda è: questo approccio è giusto o no? E se voi ragazzi lo dite, allora va bene :).
user8363

Risposte:


4

Le clip di animazione sono meglio descritte in semplici dati, come hai fatto nel tuo primo frammento XML. Puoi farlo manualmente o esportarlo da un pacchetto artistico. In entrambi i casi, probabilmente vorrai creare una pipeline che la prenda da un formato intermedio leggibile dall'uomo come XML e lo metta in qualcosa di carino e veloce da caricare.

Il prossimo passo è riuscire a renderizzare la cosa. Se stai usando una sorta di grafico di scena, probabilmente significherà creare un nodo Anim. Dovresti essere in grado di dire al nodo anim quale animazione è attualmente in riproduzione e dove si trova attualmente nella sequenza temporale. Assicurati di mantenere accessibili le informazioni sui box di delimitazione a questo livello in modo da poterle facilmente inserire nel tuo sistema di abbattimento.

Ora vorrai associare un'animazione a un'entità di gioco. Tendo a usare un modello basato su componenti, quindi per me questo significa componente AnimState. Questo è il tuo livello intermedio tra il gameplay e il rendering. Tiene traccia di quale animazione sta riproducendo un'entità, modalità di riproduzione (loop, una volta, ping-pong, ecc.), Tempistica, ecc. Può inviare eventi come "animover" all'entità e aggiorna lo stato dell'anodo quando appropriato . Gli AnimState per le entità attive verranno aggiornati una volta per tick sim se stanno riproducendo un'animazione.

Un componente animstate è probabilmente sufficiente per oggetti di gioco semplici (oggetti di scena di base e simili), ma per entità più complicate vorrai usare una macchina a stati per gestirlo. Questo è meglio espresso in un linguaggio di scripting come Lua o Python. Uno stato può avere diversi blocchi funzionali (onEnter, onExit, onUpdate, onEvent), nonché una sequenza temporale che specifica determinate azioni e trigger che dovrebbero verificarsi in determinati momenti. Probabilmente avrai una sorta di classe manager che è responsabile dell'aggiornamento di queste macchine a stati come appropriato, oltre a innescare i callback della timeline quando si verificano. Dovresti cercare di mantenere queste cose il più possibile basate sugli eventi, poiché ogni OnUpdate che scrivi sarà un costo lineare con il conteggio delle entità. Vorrai anche poter specificare i tag ("attaccare", "inattivo", "ignoreinput", ecc.) associati sia a stati interi che a determinate regioni temporali degli stati. Probabilmente avrai anche bisogno di alcuni gestori di eventi di alto livello che si applicano all'intero grafico di stato e non solo a uno stato particolare.

I personaggi "senzienti" avranno probabilmente anche una sorta di intelligenza artificiale. Tendo a creare un componente "locomotore" specifico che gestisca il camminare. Si interfaccia con lo stategraph usando un sistema di segnali ed eventi e interrogando i tag di stato, e può essere detto di "camminare verso il punto" o "correre in una certa direzione a una certa velocità". I componenti AI di livello superiore (come un albero dei comportamenti o altro) possono quindi utilizzare questa interfaccia senza preoccuparsi dei dettagli.


1

Il miglior sistema di animazione basato sui dati che ho visto finora è il Blend Tree . Davvero, è dannatamente buono e può fare tutto ciò che chiedi qui. Secondo AIGameDev.com è ora lo standard di fatto nel settore e credo che abbiano ragione.

Sfortunatamente non ho trovato una buona risorsa con un googling veloce, ma puoi provare questo o quello per avere una visione d'insieme. C'è anche un articolo a pagamento su AIGameDev.com, non so se vale la pena ottenere un account premium.


Questa è un'ottima risorsa, grazie. Sto cercando informazioni come questa.
user8363,

1
La fusione di animazioni non è possibile con fogli sprite discreti, ma solo con animazione scheletrica continua
AlexFoxGill
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.