Estados de animación controlados por datos

14

EDITAR: Para aclarar cuál es exactamente mi pregunta: ¿es esta una buena manera de manejar animaciones / estado de animación en un motor de juego con la vista puesta en la creación / gestión de contenido? ¿Cuáles son los defectos al hacerlo de esta manera y cuál sería una forma alternativa de hacerlo? - Aunque mi respuesta fue parcialmente respondida en los comentarios, ya que parece ser el camino a seguir.

Estoy tratando de manejar animaciones en un proyecto de pasatiempo de motor de juego 2D , sin codificarlas. Los estados de animación de codificación dura me parecen un fenómeno común pero muy extraño.

Un poco de historia: estoy trabajando con un sistema de entidades donde los componentes son bolsas de datos y los subsistemas actúan sobre ellos. Elegí usar un sistema de sondeo para actualizar los estados de animación.

Con estados de animación quiero decir: "walking_left", "running_left", "walking_right", "shooting", ...

Mi idea para manejar animaciones era diseñarlo como un modelo basado en datos . Los datos pueden almacenarse en un archivo xml, un rdbms, ... Y pueden cargarse al comienzo de un juego / nivel / ... De esta manera, puede editar fácilmente animaciones y transiciones sin tener que cambiar el código en todas partes en su juego.

Como ejemplo, hice un borrador xml de las definiciones de datos que tenía en mente.

Un dato muy importante sería simplemente la descripción de una animación . Una animación tendría una identificación única (un nombre descriptivo). Tendría una identificación de referencia a una imagen (la hoja de sprites que usa, porque diferentes animaciones pueden usar diferentes hojas de sprites). Los cuadros por segundo para ejecutar la animación. La "reproducción" aquí define si una animación debe ejecutarse una vez o infinitamente. Luego definí una lista de rectángulos como marcos.

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

Los datos de animación se cargarían y se mantendrían en un grupo de recursos de animación y las entidades del juego que los están utilizando harán referencia a ellos. Sería tratado como un recurso como una imagen, un sonido, una textura, ...

El segundo dato a definir sería una máquina de estados para manejar estados de animación y transiciones. Esto define cada estado en el que puede estar una entidad de juego, lo que indica que puede hacer la transición y qué desencadena ese cambio de estado.

Esta máquina de estados diferiría de una entidad a otra. Porque un pájaro podría tener estados de "caminar" y "volar" mientras que un humano solo tendría el estado de "caminar". Sin embargo, podría ser compartido por diferentes entidades porque varios humanos probablemente tendrán los mismos estados (especialmente cuando define algunos NPC comunes como monstruos, etc.). Además, un orco podría tener los mismos estados que un humano. Solo para demostrar que esta definición de estado podría ser compartida pero solo por un grupo selecto de entidades de juego .

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

Estos estados pueden ser manejados por un sistema de votación . Cada marca de juego captura el estado actual de una entidad del juego y verifica todos los disparadores. Si se cumple una condición, cambia el estado de la entidad al estado "goto".

La última parte con la que estaba luchando era cómo vincular datos de animación y estados de animación a una entidad . El enfoque más lógico me pareció agregar un puntero a los datos de la máquina de estado que usa una entidad y definir para cada estado en esa máquina qué animación usa.

Aquí hay un ejemplo xml de cómo definiría el comportamiento de la animación y la representación gráfica de algunas entidades comunes en un juego, abordando el estado de la animación y la identificación de los datos de la animación. Tenga en cuenta que tanto "asistente" como "orco" tienen los mismos estados de animación pero una animación diferente. Además, una animación diferente podría significar una hoja de sprite diferente, o incluso una secuencia diferente de animaciones (una animación podría ser más larga o más 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>

Cuando se crea la entidad, agregaría una lista de estados con datos de máquina de estado y una referencia de datos de animación.

En el futuro, usaría el sistema de entidades para construir entidades enteras definiendo componentes en un formato xml similar.

-

Esto es lo que se me ocurrió después de un poco de investigación. Sin embargo, tuve algunos problemas para entenderlo, así que esperaba algún comentario. ¿Hay algo aquí que no tiene sentido, o hay una mejor manera de manejar estas cosas? Comprendí la idea de iterar a través de cuadros, pero tengo problemas para dar un paso más y este es mi intento de hacerlo.

usuario8363
fuente
1
Se me ocurrió una idea similar para almacenar datos de animación, aunque no he considerado los desencadenantes. Aquí hay un breve artículo que escribí sobre él y un enlace a un proyecto XNA que escribí que consume el XML y maneja el lado de animación de las cosas. Tengo algunas cosas que son diferentes, como el concepto de Conjuntos y Secuencias, pero aparte de eso, creo que estás en camino.
John McDonald
2
No es que su diseño sea malo (no lo es, es muy similar a un sistema similar que construí en tiempos pasados), pero ¿cuál es exactamente su pregunta aquí? Creo que realmente podría ser más claro.
MrCranky
@ John - Gracias amigo, lo echaré un vistazo más tarde esta noche. @ MrCranky - Bueno, principalmente lo que dijiste. Si es bueno y posiblemente consejos / enlaces a métodos más establecidos. Estoy realmente en la oscuridad aquí en cuanto a experiencia.
user8363
1
Me gustaría darle un voto positivo por la profundidad de la información proporcionada, pero, para hacerme eco de MrCranky, realmente no estoy siguiendo cuál es la pregunta. Por mi propio consejo personal (que surge de haber construido este tipo de sistema hace un par de semanas), diría que estás en lo cierto.
Mike Cluck
@MikeC Esa es solo la respuesta que necesitaba. Pido disculpas por el hecho de que no pude aclarar mi pregunta. Tal vez si no fuera perfecto, se vería más como una pregunta :). El hecho es que no pude encontrar muchos recursos que trataran con estados de animación y los que lo codificaron, por lo que crear / cambiar contenido sería una pesadilla. Entonces mi pregunta es: ¿este enfoque es correcto o no? Y si ustedes dicen que sí, entonces está bien :).
user8363

Respuestas:

4

Los clips de animación se describen mejor en datos simples y antiguos, como lo hizo en su primer fragmento XML. Puede hacer esto a mano o exportarlo desde un paquete de arte. De cualquier manera, es probable que desee crear una tubería que lo tome de un formato intermedio legible para humanos como XML y lo coloque en algo agradable y rápido de cargar.

El siguiente paso es poder renderizar la cosa. Si está utilizando algún tipo de gráfico de escena, eso probablemente significará hacer un Nodo Anim para él. Debería poder decirle al nodo anim qué animación está reproduciendo actualmente y en qué parte de la línea de tiempo se encuentra actualmente. Asegúrese de mantener la información del cuadro delimitador accesible en este nivel para poder alimentarla fácilmente en su sistema de selección.

Ahora, querrás asociar una animación con una entidad de juego. Tiendo a usar un modelo basado en componentes, así que para mí esto significa un componente AnimState. Esta es tu capa intermedia entre el juego y el renderizado. Realiza un seguimiento de la animación que está reproduciendo una entidad, los modos de reproducción (bucle, una vez, ping-pong, etc.), el tiempo, etc. Puede enviar eventos como "animover" a la entidad y actualiza el estado del animnode cuando sea apropiado . AnimStates para entidades activas se actualizará una vez por simulación si están reproduciendo una animación.

Probablemente, un componente animstate sea suficiente para elementos de juego simples (accesorios básicos de fondo y similares), pero para entidades más complicadas querrás usar una máquina de estado para administrarlo. Esto se expresa mejor en un lenguaje de script como Lua o Python. Un estado puede tener varios bloques funcionales (onEnter, onExit, onUpdate, onEvent), así como una línea de tiempo que especifica ciertas acciones y desencadenantes que deberían ocurrir en ciertos momentos. Probablemente tendrá algún tipo de clase de administrador responsable de actualizar estas máquinas de estado según corresponda, así como de activar las devoluciones de llamada de la línea de tiempo cuando ocurran. Debe intentar mantener estas cosas lo más basadas en eventos posible, ya que cada OnUpdate que escriba será un costo lineal con recuento de entidades. También querrá poder especificar etiquetas ('atacar', 'inactivo', 'ignoreinput', etc.) que están asociados tanto con estados completos como con ciertas regiones temporales de estados. Probablemente también desee algunos controladores de eventos de alto nivel que se apliquen a todo el gráfico de estado, y no solo a un estado en particular.

Los personajes 'sensibles' probablemente también tendrán algún tipo de IA. Tiendo a hacer un componente 'locomotor' específico que maneja caminar. Se interconecta con el gráfico de estado utilizando un sistema de señales y eventos y preguntando por etiquetas de estado, y se le puede decir que "camine hasta el punto" o "corra en una dirección determinada a una velocidad determinada". Los componentes de IA de nivel superior (como un árbol de comportamiento o lo que sea) pueden usar esta interfaz sin preocuparse por los detalles.

Kevin
fuente
1

El mejor sistema de animación basado en datos que he visto hasta ahora es el Blend Tree . Realmente, es muy bueno y puede hacer todo lo que estás pidiendo aquí. Según AIGameDev.com, ahora es el estándar de facto en la industria, y creo que tienen razón.

Desafortunadamente, no encontré un buen recurso con una búsqueda rápida en Google, pero puede intentar esto o aquello para obtener una descripción general. También hay un artículo de pago en AIGameDev.com, no sé si vale la pena obtener una cuenta premium.

Laurent Couvidou
fuente
Este es un muy buen recurso, gracias. Estoy buscando información como esta.
user8363
1
No es posible
mezclar