Estados de animação controlados por dados

14

EDIT: Para esclarecer qual é exatamente a minha pergunta: esta é uma boa maneira de lidar com animações / estado de animação em um mecanismo de jogo com o olho na criação / gerenciamento de conteúdo? Quais são as falhas em fazê-lo dessa maneira e qual seria uma maneira alternativa de fazê-lo? - Embora minha resposta tenha sido parcialmente respondida nos comentários, como parece ser o caminho a percorrer.

Estou tentando lidar com animações em um projeto de hobby de mecanismo de jogo 2D , sem codificá-las. Estados de animação de codificação embutida me parecem um fenômeno comum, mas muito estranho.

Um pouco de experiência: estou trabalhando com um sistema de entidades em que componentes são sacos de dados e subsistemas atuam sobre eles. Eu escolhi usar um sistema de votação para atualizar os estados de animação.

Com estados de animação, quero dizer: "walking_left", "running_left", "walking_right", "shooting", ...

Minha idéia para lidar com animações foi projetá-la como um modelo orientado a dados . Os dados podem ser armazenados em um arquivo xml, rdbms, ... E podem ser carregados no início de um jogo / nível / ... Dessa forma, você pode editar facilmente animações e transições sem precisar alterar o código em qualquer lugar do jogos.

Como exemplo, fiz um rascunho xml das definições de dados que eu tinha em mente.

Um dado muito importante seria simplesmente a descrição de uma animação . Uma animação teria um ID exclusivo (um nome descritivo). Ele conteria um ID de referência para uma imagem (a folha de sprite que ela usa, porque diferentes animações podem usar folhas de sprite diferentes). Os quadros por segundo para executar a animação. O "replay" aqui define se uma animação deve ser executada uma vez ou infinitamente. Então defini uma lista de retângulos como quadros.

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

Os dados da animação seriam carregados e mantidos em um pool de recursos de animação e referenciados pelas entidades do jogo que os estão usando. Seria tratado como um recurso como uma imagem, um som, uma textura, ...

O segundo dado a ser definido seria uma máquina de estados para manipular estados e transições de animação . Isso define cada estado em que uma entidade do jogo pode estar, em quais estados pode fazer a transição e o que aciona essa alteração de estado.

Essa máquina de estado seria diferente de entidade para entidade. Porque um pássaro pode ter estados "andando" e "voando", enquanto um humano teria apenas o estado "andando". No entanto, pode ser compartilhado por diferentes entidades, porque vários seres humanos provavelmente terão os mesmos estados (especialmente quando você define alguns NPCs comuns, como monstros, etc.). Além disso, um orc pode ter os mesmos estados que um humano. Apenas para demonstrar que essa definição de estado pode ser compartilhada, mas apenas por um grupo selecionado de entidades do jogo .

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

Esses estados podem ser tratados por um sistema de votação . Cada marca de jogo captura o estado atual de uma entidade do jogo e verifica todos os gatilhos. Se uma condição for atendida, ele altera o estado da entidade para o estado "goto".

A última parte com a qual eu estava lutando era como vincular dados de animação e estados de animação a uma entidade . A abordagem mais lógica me pareceu adicionar um ponteiro aos dados da máquina de estado que uma entidade usa e definir para cada estado nessa máquina qual animação ela usa.

Aqui está um exemplo xml de como eu definiria o comportamento da animação e a representação gráfica de algumas entidades comuns em um jogo, abordando o estado da animação e o ID dos dados da animação. Observe que "wizard" e "orc" têm os mesmos estados de animação, mas uma animação diferente. Além disso, uma animação diferente pode significar uma folha de sprite diferente ou mesmo uma sequência diferente de animações (uma animação pode ser maior ou menor).

<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 a entidade está sendo criada, ela adiciona uma lista de estados com dados da máquina de estados e uma referência de dados de animação.

No futuro, eu usaria o sistema de entidades para construir entidades inteiras, definindo componentes em um formato xml semelhante.

-

É isso que eu inventei depois de algumas pesquisas. No entanto, tive alguns problemas para contornar a questão, então estava esperando algum feedback. Existe algo aqui que não faz sentido, ou existe uma maneira melhor de lidar com essas coisas? Compreendi a ideia de iterar pelos quadros, mas estou tendo problemas para dar um passo adiante e essa é minha tentativa de fazer isso.

user8363
fonte
1
Eu tive uma idéia semelhante para armazenar dados de animação, embora não tenha considerado os gatilhos. Aqui está um pequeno artigo que escrevi sobre isso e um link para um projeto XNA que consome o XML e lida com o lado da animação. Eu tenho algumas coisas diferentes, como o conceito de Conjuntos e Sequências, mas, além disso, acho que você está no caminho certo.
9788 John McDonald
2
Não que seu projeto seja ruim (não é, é muito parecido com um sistema semelhante que eu construí no passado), mas qual é exatamente a sua pergunta aqui? Eu acho que realmente poderia ser mais claro.
MrCranky
@ John - Obrigado companheiro, vou dar uma olhada mais tarde esta noite. @ MrCranky - Bem, principalmente apenas o que você disse. Se houver algum bom e, possivelmente, dicas / links para métodos mais estabelecidos. Estou realmente no escuro aqui em termos de experiência.
user8363
1
Eu gostaria de dar um voto positivo para a profundidade das informações fornecidas, mas, para repetir MrCranky, não estou realmente seguindo qual é a pergunta. Para meu próprio conselho pessoal (que resulta de ter construído esse tipo de sistema há algumas semanas), eu diria que você está no local.
quer
@ MikeC Essa é apenas a resposta que eu precisava. Peço desculpas pelo fato de não ter sido capaz de esclarecer minha pergunta. Talvez se eu não estivesse no local pareceria mais uma pergunta :). O fato é que não consegui encontrar muitos recursos que lidavam com os estados de animação e os que a codificaram de maneira embutida, para criar / alterar conteúdo seria um pesadelo. Então, minha pergunta é: essa abordagem está correta ou não? E se vocês dizem que sim, tudo bem :).
precisa saber é o seguinte

Respostas:

4

Os clipes de animação são melhor descritos em dados antigos simples, como você fez no seu primeiro snippet XML. Você pode fazer isso manualmente ou exportar para ele a partir de um pacote de arte. De qualquer forma, você provavelmente desejará criar um pipeline que o leve a partir de um formato intermediário legível por humanos, como XML, e o coloque em algo agradável e rápido de carregar.

O próximo passo é ser capaz de renderizar a coisa. Se você estiver usando algum tipo de gráfico de cena, isso provavelmente significará criar um Nó Anim para ele. Você deve poder dizer ao nó anim qual animação está sendo executada no momento e onde está atualmente na linha do tempo. Certifique-se de manter as informações da caixa delimitadora acessíveis nesse nível, para poder alimentá-las facilmente em seu sistema de seleção.

Agora, você deseja associar uma animação a uma entidade do jogo. Eu costumo usar um modelo baseado em componentes, então para mim isso significa e o componente AnimState. Esta é a sua camada intermediária entre jogabilidade e renderização. Ele monitora qual animação uma entidade está reproduzindo, modos de reprodução (loop, uma vez, pingue-pongue, etc), tempo etc. Ele pode enviar eventos como "animover" de volta para a entidade e atualiza o estado do animnode quando apropriado . Os AnimStates para entidades ativas serão atualizados uma vez por tick de sim, se estiverem reproduzindo uma animação.

Um componente animstate é provavelmente suficiente para itens simples do jogo (adereços básicos de plano de fundo e similares), mas para entidades mais complicadas você vai querer usar uma máquina de estado para gerenciá-la. Isso é melhor expresso em uma linguagem de script como Lua ou Python. Um estado pode ter vários blocos funcionais (onEnter, onExit, onUpdate, onEvent), bem como uma linha do tempo que especifica certas ações e gatilhos que devem ocorrer em determinados momentos. Você provavelmente terá algum tipo de classe de gerente responsável por atualizar essas máquinas de estado conforme apropriado, além de acionar os retornos de chamada da linha do tempo quando eles ocorrerem. Você deve tentar manter essas coisas o mais baseadas em eventos possível, pois todo OnUpdate que você escreve terá um custo linear com a contagem de entidades. Você também pode especificar tags ('atacando', 'inativo', 'ignoreinput' etc) associados a estados inteiros e a determinadas regiões temporais dos estados. Você provavelmente também desejará alguns manipuladores de eventos de alto nível que se apliquem a todo o gráfico de estado, e não apenas a um estado específico.

Personagens 'sencientes' provavelmente terão algum tipo de IA também. Costumo fazer um componente 'locomotor' específico que lida com a caminhada. Ele faz interface com o gráfico estratégico usando um sistema de sinais e eventos e consulta de tags de estado, e pode ser dito para "caminhar até o ponto" ou "correr em uma determinada direção a uma certa velocidade". Os componentes de IA de nível superior (como uma árvore de comportamento ou qualquer outra coisa) podem usar essa interface sem se preocupar com os detalhes.

Kevin
fonte
1

O melhor sistema de animação orientado a dados que eu vi até agora é a Blend Tree . Realmente, é muito bom e pode fazer tudo o que você está pedindo aqui. Segundo o AIGameDev.com, agora é o padrão de fato do setor e acredito que eles estejam certos.

Infelizmente, não encontrei um bom recurso para pesquisar rapidamente no Google, mas você pode tentar isso ou aquilo para obter uma visão geral. Há também um artigo pago no AIGameDev.com, não sei se vale a pena obter uma conta premium.

Laurent Couvidou
fonte
Este é um recurso muito bom, obrigado. Estou procurando informações como esta.
user8363
1
Misturando animações não é possível com sprite folhas discretas, apenas com animação esquelético contínua
AlexFoxGill