États d'animation pilotés par les données

14

EDIT: Pour clarifier quelle est exactement ma question: est-ce un bon moyen de gérer les animations / l'état d'animation dans un moteur de jeu avec un œil sur la création / gestion de contenu? Quels sont les défauts de le faire de cette façon et quelle serait une autre façon de le faire? - Bien que ma réponse ait été partiellement répondue dans les commentaires, car cela semble être la voie à suivre.

J'essaie de gérer des animations dans un projet de passe-temps de moteur de jeu 2D , sans les coder en dur. Les états d'animation codés en dur me semblent être un phénomène courant mais très étrange.

Un peu d'histoire: je travaille avec un système d'entités où les composants sont des sacs de données et les sous-systèmes agissent sur eux. J'ai choisi d'utiliser un système d'interrogation pour mettre à jour les états d'animation.

Avec les états d'animation, je veux dire: "walking_left", "running_left", "walking_right", "shooting", ...

Mon idée pour gérer les animations était de le concevoir comme un modèle piloté par les données . Les données pourraient être stockées dans un fichier xml, un rdbms, ... Et pourraient être chargées au début d'un jeu / niveau / ... De cette façon, vous pouvez facilement éditer des animations et des transitions sans avoir à aller changer le code partout dans votre Jeu.

À titre d'exemple, j'ai fait un brouillon xml des définitions de données que j'avais en tête.

Une donnée très importante serait simplement la description d'une animation . Une animation aurait un identifiant unique (un nom descriptif). Il contiendrait un identifiant de référence à une image (la feuille de sprites qu'il utilise, car différentes animations peuvent utiliser différentes feuilles de sprites). Les images par seconde pour exécuter l'animation. Le "replay" définit ici si une animation doit être exécutée une fois ou à l'infini. Ensuite, j'ai défini une liste de rectangles comme cadres.

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

Les données d'animation seraient chargées et conservées dans un pool de ressources d'animation et référencées par les entités de jeu qui les utilisent. Il serait traité comme une ressource comme une image, un son, une texture, ...

La deuxième donnée à définir serait une machine à états pour gérer les états d'animation et les transitions. Cela définit chaque état dans lequel une entité de jeu peut se trouver, ce qui indique qu'elle peut effectuer une transition et ce qui déclenche ce changement d'état.

Cette machine d'état diffère d'une entité à l'autre. Parce qu'un oiseau pourrait avoir des états "marcher" et "voler" alors qu'un humain n'aurait que l'état "marcher". Cependant, il pourrait être partagé par différentes entités car plusieurs humains auront probablement les mêmes états (surtout lorsque vous définissez des PNJ communs comme des monstres, etc.). De plus, un orc peut avoir les mêmes états qu'un humain. Juste pour démontrer que cette définition d'état peut être partagée mais uniquement par un groupe sélectionné d'entités de jeu .

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

Ces états peuvent être gérés par un système de sondage . À chaque partie, il capture l'état actuel d'une entité de jeu et vérifie tous les déclencheurs. Si une condition est remplie, elle change l'état de l'entité en l'état "goto".

La dernière partie avec laquelle je me débattais était de savoir comment lier des données d'animation et des états d'animation à une entité . L'approche la plus logique m'a semblé ajouter un pointeur sur les données de la machine d'état qu'une entité utilise et définir pour chaque état de cette machine quelle animation elle utilise.

Voici un exemple xml de la façon dont je définirais le comportement d'animation et la représentation graphique de certaines entités communes dans un jeu, en abordant l'état d'animation et l'identifiant des données d'animation. Notez que "wizard" et "orc" ont les mêmes états d'animation mais une animation différente. En outre, une animation différente peut signifier une feuille de sprite différente, ou même une séquence d'animations différente (une animation peut être plus ou moins longue).

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

Lorsque l'entité est en cours de création, elle ajouterait une liste d'états avec des données de machine d'état et une référence de données d'animation.

À l'avenir, j'utiliserais le système d'entités pour créer des entités entières en définissant des composants dans un format xml similaire.

-

C'est ce que j'ai trouvé après quelques recherches. Cependant, j'ai eu du mal à m'en sortir, alors j'espérais avoir des retours. Y a-t-il quelque chose ici qui n'a pas de sens, ou existe-t-il une meilleure façon de gérer ces choses? J'ai saisi l'idée d'itérer à travers des cadres mais j'ai du mal à aller plus loin et c'est ma tentative de le faire.

user8363
la source
1
J'ai trouvé une idée similaire pour stocker des données d'animation, bien que je n'ai pas considéré les déclencheurs. Voici un court article que j'ai écrit à ce sujet et un lien vers un projet XNA que j'ai écrit qui consomme le XML et gère le côté animation des choses. J'ai quelques choses qui sont différentes, comme le concept des ensembles et des séquences, mais à part ça, je pense que vous êtes sur la bonne voie.
John McDonald
2
Non pas que votre conception soit mauvaise (ce n'est pas le cas, elle s'inscrit beaucoup dans la lignée d'un système similaire que j'ai construit autrefois), mais quelle est exactement votre question ici? Je pense que cela pourrait vraiment être plus clair.
MrCranky
@ John - Merci mon pote, je vais y jeter un œil plus tard ce soir. @ MrCranky - Eh bien, surtout ce que vous avez dit. S'il s'agit de bons et éventuellement de conseils / liens vers des méthodes plus établies. Je suis vraiment dans le noir ici en termes d'expérience.
user8363
1
Je voudrais donner une note positive à la profondeur des informations fournies, mais, pour faire écho à M. Cranky, je ne suis pas vraiment en train de suivre la question. Pour mes propres conseils personnels (qui découlent de la construction de ce type de système il y a quelques semaines), je dirais que vous êtes sur place.
Mike Cluck
@MikeC C'est juste la réponse dont j'avais besoin. Je m'excuse de ne pas avoir été plus clair sur ma question. Peut-être que si je n'étais pas sur place, cela ressemblerait plus à une question :). Le fait est que je n'ai pas trouvé beaucoup de ressources traitant des états d'animation et de celles qui l'ont codé en dur, donc créer / changer du contenu serait un cauchemar. Ma question est donc la suivante: cette approche est-elle correcte ou non? Et si vous le dites, c'est bien :).
user8363

Réponses:

4

Les clips d'animation sont mieux décrits dans les données anciennes, comme vous l'avez fait dans votre premier extrait de code XML. Vous pouvez le faire à la main ou l'exporter à partir d'un package artistique. Quoi qu'il en soit, vous souhaiterez probablement créer un pipeline qui le prendra à partir d'un format intermédiaire lisible par l'homme comme XML et le placera dans quelque chose de agréable et rapide à charger.

La prochaine étape consiste à rendre la chose. Si vous utilisez une sorte de graphique de scène, cela signifiera probablement la création d'un nœud d'animation pour cela. Vous devriez être en mesure de dire au nœud d'animation quelle animation il joue actuellement et où il se trouve actuellement dans la chronologie. Assurez-vous de conserver les informations de la zone de délimitation accessibles à ce niveau afin de pouvoir les insérer facilement dans votre système de tri.

Maintenant, vous allez vouloir associer une animation à une entité de jeu. J'ai tendance à utiliser un modèle basé sur les composants, donc pour moi, cela signifie et le composant AnimState. Il s'agit de votre couche intermédiaire entre le gameplay et le rendu. Il garde la trace de l'animation en cours de lecture d'une entité, des modes de lecture (boucle, une fois, ping-pong, etc.), du timing, etc. . AnimStates pour les entités actives sera mis à jour une fois par tick de simulation si elles jouent une animation.

Un composant animstate est probablement suffisant pour les éléments de jeu simples (accessoires d'arrière-plan de base et similaires), mais pour les entités plus complexes, vous allez vouloir utiliser une machine d'état pour le gérer. Cela s'exprime mieux dans un langage de script comme Lua ou Python. Un état peut avoir plusieurs blocs fonctionnels (onEnter, onExit, onUpdate, onEvent), ainsi qu'une chronologie qui spécifie certaines actions et déclencheurs qui devraient se produire à certains moments. Vous aurez probablement une sorte de classe de gestionnaire qui est responsable de la mise à jour de ces machines d'état, le cas échéant, ainsi que du déclenchement des rappels de la chronologie lorsqu'ils se produisent. Vous devriez essayer de garder ces choses aussi basées que possible sur les événements, car chaque OnUpdate que vous écrivez sera un coût linéaire avec le nombre d'entités. Vous voudrez également pouvoir spécifier des balises ("attaque", "inactif", 'ignoreinput', etc.) qui sont associés à la fois à des états entiers et à certaines régions temporelles d'états. Vous voudrez probablement aussi des gestionnaires d'événements de haut niveau qui s'appliquent à l'ensemble du graphique d'état, et pas seulement à un état particulier.

Les personnages «sensibles» auront probablement aussi une sorte d'IA. J'ai tendance à créer un composant «locomoteur» spécifique qui gère les déplacements. Il s'interface avec le stratège à l'aide d'un système de signaux et d'événements et interroge les étiquettes d'état, et peut être invité à «marcher jusqu'au point», ou «courir dans une certaine direction à une certaine vitesse». Les composants d'IA de niveau supérieur (comme un arbre de comportement ou autre) peuvent ensuite utiliser cette interface sans se soucier des détails.

Kevin
la source
1

Le meilleur système d'animation basé sur les données que j'ai vu jusqu'à présent est l' arbre de fusion . Vraiment, c'est sacrément bon et il peut faire tout ce que vous demandez ici. Selon AIGameDev.com, c'est désormais la norme de facto dans l'industrie, et je pense qu'ils ont raison.

Malheureusement, je n'ai trouvé aucune bonne ressource avec une recherche rapide sur Google, mais vous pouvez essayer ceci ou cela pour obtenir un aperçu. Il y a aussi un article payant sur AIGameDev.com, je ne sais pas si cela vaut la peine d'obtenir un compte premium.

Laurent Couvidou
la source
Ceci est une très bonne ressource, merci. Je recherche des informations comme celle-ci.
user8363
1
Le mélange d'animations n'est pas possible avec des feuilles de sprite discrètes, seulement avec une animation squelettique continue
AlexFoxGill