1

yop,

J'aurais besoin de conseils pour trouver une bonne méthode pour gérer des personnages (dans un jeu, bien sûr). J'ai un personnage, qui contient tout un tas d'informations dont le modèle à afficher quand on veut le dessiner à l'écran, et les animations disponibles pour ce personnage. J'ai également toutes les méthodes nécessaires pour déplacer le personnage (sauter, avancer, reculer, etc), et pour déclancher des animations (quand je dis "déplacer", c'est tout à fait séparé des animations, il s'agit juste de modifications des coordonnées).

J'aimerais avoir un système qui me permette de contrôler les actions mon personnage (soit au clavier, soit au travers d'une fonction qui jouera le rôle d'IA), mais où il y aurait le minimum possible de paramètres codés en dur (j'ai plusieurs modèles, qui n'ont pas les mêmes animations et qui n'auront pas exactement les mêmes comportements, donc si j'écris quelque part "function avancer () { vitesse (10); animation ("marche_avant"); }", ça ne marchera que pour ce modèle là puisque rien ne dit qu'un autre personnage peut marcher également, et encore moins que son animation de marche s'appelle "marche_avant".

Une autre contrainte est que toutes les actions ne sont pas déclanchables n'importe quand, et certaines ont la priorité sur d'autres (si on se prend un coup, l'action "se prendre un coup" qui fait reculer le perso et joue une animation où il vacille doit interrompre quasiment toutes les autres quand elle se déclanche). Certaines animations ont également la priorité, sans pour autant interdire aux autres de fonctionner (si on tourne sur soi-même, une animation spéciale est jouée; si on cours, une animation de course est jouée, si on tourne et qu'on cours, ça marche, mais seule l'animation de course est jouée).

Enfin, quand des actions sont compatibles, elles peuvent très bien déclancher des animations sur des parties séparées du personnage (il peut par exemple courir et donner un coup d'épée, la 1ere animation utilisant les jambes et la 2eme les bras, ça ne pose pas de problème).

Toutes mes tentatives pour le moment se sont résumées à :
- Beaucoup trop de code en dur, donc obligé de faire plein de fichiers pour les différents personnages
- Un code très lourd à cause de tous les cas particuliers

Quelqun aurait déjà pensé à des solutions efficaces à ce genre de problème ? Merci happy
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

2

Ca ne répond pas à la question principale, mais y'a déjà un truc intéressant que tu peux regarder pour gérer tes animations, c'est une sorte d'"animation blending". L'idée ce serait de permettre de superposer des animations différentes (sans contrainte sur les parties gérées par chaque). Un peu comme le vertex blending si tu veux mais dans le temps au lieu d'être dans l'espace.

Sinon, je pense que de toutes façons tu devrais fixer les noms des animations : marche_avant sera l'animation de marche pour tous les personnages. En revanche, chaque personnage serait un "espace de nommage" pouvant avoir sa propre fonction marche_avant.

3

Pour le blending c'est fait, en gros les parties "animation" et "déplacement" (mais seulement au sens "modification des coordonnées", avec collisions et tout) sont terminées et marchent à peu près.

Pour les noms communs des animations, j'esperais qu'il existe une solution qui n'impose pas ça, mais c'est pê pas possible en effet :/
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

4

C'est en procédural ou en orienté objet ?
L'exemple donné a tout l'air d'être procédural, malheureusement.
En effet, ce serait beaucoup plus simple en orienté objet, la proposition de spectras d'espace de nommage par personnage n'étant d'ailleurs ni plus ni moins que de l'implémentation objet wink !
Ainsi, tu fais une classe abstraite "Personnage" avec une fonction marcher (abstraite ou concrète avec des valeurs par défaut), dont dérivent tes différentes classes de persos (certaines classes définissant un personnage très précis n'étant alors instanciées qu'une seule fois, cf. le pattern singleton) qui implémentent ou redéfinissent marcher (la classe "Vieillard" utilisera une vitesse de 1, la classe "Sprinter", une vitesse de 42, par exemple).

Pour ce qui est des priorités des actions, je pense que l'on pourrait utiliser un attribut prioriteActionioriteAction = priorite ; /* code kivabien */ this.prioriteAction = 0 ; }
 qui vaut 0 au repos, et qui est vérifiée et modifiée par les différentes actions.void marcher() {
	priorite = 7 ;
	if ( priorite < this.prioriteAction )
		return ;
	this.pr
D'ailleurs, si les priorités d'une action donnée sont les mêmes pour tout le monde, plutôt que copier/coller la valeur 7 pour toutes les méthodes marcher implémentées, je pense qu'il serait intéressant de regrouper toutes les méthodes marcher dans la même classe pour factoriser du code, et d'utiliser le pattern visiteur (pas évident à appréhender la première fois, mais vraiment puissant quand on l'a compris).

Sinon, sans rapport avec la choucroute : il est impossible de déclancher quelque chose, par contre, il est beaucoup plus simple de le déclencher tongue...
avatar
Je ne suis pas développeur Java : je suis artiste Java.
Ce que l’on conçoit bien s’énonce clairement, / Et le code pour l’écrire arrive aisément.
Hâtez-vous lentement ; toujours, avec méthode, / Vingt fois dans l’IDE travaillez votre code.
La perfection est atteinte, non pas lorsqu’il n’y a plus rien à ajouter, mais lorsqu’il n’y a plus rien à retirer.
You don't use science to show that you're right, you use science to become right.

5

hmm je vais implémenter ça en java, donc en objet, et pour "appréhender les design pattern" il ne devrait pas y avoir de problème ^^ (même si l'utilisation d'un singleton ici ne me semble pas indispensable, tes classes "racine" devraient être abstraites et donc jamais instanciées; mais après tout c'est *le* design pattern que tout le monde veut caser partout grin)

sinon l'idée est bonne et pourrait être creusée, à ceci près qu'elle n'apporte pas grand chose d'utile pour les actions simultanées : il faudrait peut-être un systeme de pile dans certains cas, par exemple quand le perso tourne sur lui-même, une animation est jouée; si il décide de courir en même temps, l'animation de course prend le dessus mais le perso continue à tourner (au niveau des rotations je veux dire, puisque l'animation est totalement coupée), et si il s'arrête tout en continuant à tourner alors l'animation précédente réapparait puisqu'elle n'est plus "masquée" par celle de la course.

un autre point négatif : ta solution implique 100% du code en dur, ce que je trouve un peu dommage (j'avais pensé à un fichier de configuration externe, qui décrive les états, les animations associées, etc; mais c'est difficile d'y rendre descriptibles toutes les contraintes nécessaires)

dernière chose : c'est ma faute, je n'ai pas développé cette contrainte dans le 1er post (j'ai juste dit "toutes les actions ne sont pas déclenchables n'importe quand"), mais certaines actions peuvent nécessiter d'être déjà dans tel ou tel état avant de pouvoir être activées, ou au contraire de ne pas être dans tel ou tel état (par exemple il est impossible de sauter si on est en train de donner un coup d'épée).

le problème vient du fait qu'il y a *beaucoup* de contraintes; chaque solution que je pensais avoir trouvée en oubliait minimum une, et la bricoler par dessus casse souvent toute l'élegance de la méthode sad
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

6

Nan nan, je m'en fous du pattern singleton, je ne cherche pas à la caser, surtout que je me suis rendu compte ce midi qu'il est loin d'être indispensable si tu fais tes instanciations comme il faut.
Quand je parle d'unicité d'instanciation, je pense à certains persos spéciaux aux caractéristiques précises et qui ne peuvent exister qu'en un seul exemplaire, par unicité de l'individu (par exemple, LE héros sauveur du monde que l'on dirige ou LE grand méchant qu'il faut battre à la fin).
Et je ne parlais pas des difficultés pour comprendre les design patterns en général, mais le pattern visiteur en particulier (enfin bon, après un exemple expliqué, ça passe tout seul).

Pour le code en dur, je n'avais pas compris que tu voulais faire des fichiers de configuration externes.
Tu as quelques exemples déjà implémentés, que je voie ce à quoi tu penses ?

Pour les actions qui permettent de passer d'un état à l'autre avec des contraintes sur l'état antérieur (être debout pour pouvoir marcher, ne pas être en train de donner un coup d'épée pour pouvoir sauter) et la possibilité d'état composites (courir et tourner en même temps), le plus simple est, je pense, un automate déterministe dont les transitions sont les déclenchements d'action et les arrêts d'action (exemple : on est dans l'état "course" (avec l'animation correspondante), le déclenchement de l'action "tourner" fait passer dans l'état "course en tournant" (avec l'animation de course, d'après ce que tu dis, voir une animation spécifique), l'arrêt de l'action "courir" (c'est-à-dire le déclenchement de l'action "ne plus courir" ou "courir-barre") fait passer dans l'état "marche en tournant").
Et pour ne pas se mélanger les pinceaux, une convention possible : les noms d'états sont des substantifs ou associations de substantifs, les noms d'actions sont des verbes.
Cet automate (qui permet donc de gérer automatiquement les "priorités", avec plus de latitude) est donc représenté par une grosse matrice NxM (N = nombre d'états, M = nombre d'actions (un arrêt d'action est une action).
Après, libre à toi d'implémenter cette matrice comme tu le souhaites (tableau 2D pour des indexations numériques, HashMap de HashMap pour des indexations par Strings, etc.).
avatar
Je ne suis pas développeur Java : je suis artiste Java.
Ce que l’on conçoit bien s’énonce clairement, / Et le code pour l’écrire arrive aisément.
Hâtez-vous lentement ; toujours, avec méthode, / Vingt fois dans l’IDE travaillez votre code.
La perfection est atteinte, non pas lorsqu’il n’y a plus rien à ajouter, mais lorsqu’il n’y a plus rien à retirer.
You don't use science to show that you're right, you use science to become right.

7

La solution d'un automate me semble effectivement très interessante, j'y avais reflechi, puis j'ai voulu commencer à écrire un XML qui décrive les différents états, et là echec grin
Le problème était toujours au niveau des cas particuliers; par exemple les actions s'enchainent et retournent à l'état précedent une fois terminées, mais il existe certaines actions (se prendre un coup) qui doivent annuler certaines précedentes (marcher, donner un coup). Ça parait rien, mais y'en a tellement qu'à la fin le XML était illisible grin

(en fait le pb c'est que je vais avoir du mal à expliquer ici tout ce que je voudrais que ça gère, parceque si j'arrivais à le faire j'aurais résolu plus de la moitié du problème ^^)

Je vais essayer de creuser l'idée de l'automate, y'a surement une solution en cherchant par là, mci happy
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

8

il faudrait peut-être un systeme de pile dans certains cas, par exemple quand le perso tourne sur lui-même, une animation est jouée; si il décide de courir en même temps, l'animation de course prend le dessus mais le perso continue à tourner (au niveau des rotations je veux dire, puisque l'animation est totalement coupée)


C'est un peu décalé de la question initiale, mais =>
C'est précisément le genre de choses où tu peux tirer parti de l'animation blending. Si l'une des animations consiste à faire pivoter les pieds sucessivement et l'autre à courir, en utilisation du blending d'animation, tu auras le cumul des deux : le bonhomme courra avec une rotation des pieds. Pour que ça rende bien évidemment faut bien pondérer les deux animations (par exemple dire que lorsque le bonhomme court, les torsions générées par l'animation de rotation sont d'autant plus faibles que le bonhomme court vite). Et examiner leur synchro minutieusement aussi, mais ça c'est du goût, c'est plus du dev.

9

HS
à propos du visitor, quand on a pas la possibilité de faire une classe amie (java par exemple), on est obligé de mettre des accesseurs sur tous les attributs privés de la classe à visiter dont on a besoin, non ?
/HS

10

spectras
: C'est précisément le genre de choses où tu peux tirer parti de l'animation blending. Si l'une des animations consiste à faire pivoter les pieds sucessivement et l'autre à courir, en utilisation du blending d'animation, tu auras le cumul des deux : le bonhomme courra avec une rotation des pieds. Pour que ça rende bien évidemment faut bien pondérer les deux animations (par exemple dire que lorsque le bonhomme court, les torsions générées par l'animation de rotation sont d'autant plus faibles que le bonhomme court vite). Et examiner leur synchro minutieusement aussi, mais ça c'est du goût, c'est plus du dev.

Ça peut être interessant oui, mais dans mon cas l'animation où le perso tourne sur lui-même est totalement incompatible avec celle de la course (difficile à décrire, mais quand il pivote il croise les jambes, ça donnerait un résultat vraiment louche). Mais c'est à retenir quand même, ça pourrait servir dans un autre cas ^^
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

11

Cet article sur le sujet est particulièrement bien => http://www.gamasutra.com/features/20030704/edsall_pfv.htm
(remarque, presque tous les articles de gamasutra sont de très bonne facture happy)

12

Bon voilà, j'ai fait un automate, et ça semble marcher pas trop mal (enfin j'ai pas encore codé tout ce que ça faisait avant, mais le peu qui est fait a bien meilleure tête ^^)

Par contre un point négatif : les états sont stockés dans un fichier XML, et identifiés par leur nom qui est une chaine. Je pourrais prendre comme convention que tous les noms doivent être des entiers, mais ça serait très vite illisible à la fois dans le XML ("état 13, possibilités de passage à l'état 27 et l'état 51") et dans le code ("aller à l'état 24 si possible"). Mais du coup je me tape des comparaisons de chaines à chaque fois que des états sont traversés, ce qui est franchement pas terrible coté optimisation... Mais je ne vois pas trop de solution pour avoir des états numériques et des "#defines" dans le code qui rendraient ça un peu plus lisible (gotoState (RUN_FORWARD), gotoState (JUMP), etc, plutot que gotoState (31)), puisqu'il n'y a pas moyen d'avoir les bons #defines (à moins de se dire "je sais quel tel état aura pour numéro 13", mais c'est assez hazardeux comme méthode, et puis si je rajoute un état faut changer tous les defines).

Quelqun aurait une solution à ça ? (sinon je laisse les chaines tant pis, mais bon :/)
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

13

les #defines tu peux pas les faire avec des entités en XML ?
euh en fait je ne comprends pas ton truc, si tu numérotes tous les états en partant de 1 et en incrémentant de 1 chaque fois que tu ajoutes un nouvel état quel est le problème confus

Si j'ai bien compris, tu utilises un fichier XML pour le stockage des états mais ton code n'a pas besoin de lire ce fichier pour savoir quels états existent, il le sait déjà avant ?
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

14

bah ça marcherait (enfin actuellement non mais bon ça pourrait marcher sans trop de pb), mais il n'y aurait aucun "lien" entre le XML et le code. Si je fais un #define JUMP 13, et que je vais éditer le XML, y'a des chances que l'état "jump" ne soit plus le 13, et qu'il faille modifier tous les #defines au dessus de 13 >_<

(ça pourrait être résolu en mettant directement des nombres comme identifiants d'état, mais le XML deviendrait totalement illisible)
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

15

mais si tu fais le remplacement aussi dans le XML ? genre :
<!DOCTYPE automate [
  <!ENTITY run_forward "0">
  <!ENTITY jump "1">
  ...
]>
<automate>
  <state name="&run_forward;">
     <transition dest="&jump;">
...

?
edit : en fait si je comprends bien tu as plein de fichiers XML pour gérer les différents types de personnages et leurs capacités qui sont différentes, mais les noms des états sont toujours les mêmes ? dans ce cas tu peux utiliser les entités mais en les déclarant dans une DTD externe, c'est le plus simple, mais il faut vérifier que ton parseur XML va bien aller chercher les entités externes (un parseur non validant n'est pas obligé de le faire, je crois, mais il peut le faire quand même ; je ne sais pas ce que tu utilises).

genre tu mets tout dans automate.dtd avec le reste de la DTD si tu en as déjà fait une, et après tu commences tous tes documents par <!DOCTYPE automate SYSTEM "automate.dtd">

N.B. si tu as déjà une DTD externe mais que tu veux quand même définir les entités dans le document lui-même, tu peux aussi :
<!DOCTYPE automate SYSTEM "automate.dtd" [déclarations locales]>
ça ça inclut d'abord la DTD externe et ça lui ajoute ensuite les déclarations locales (avec override le cas échéant, il me semble)
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

16

ah ça peut être pas mal, je connaissais pas ça, merci happy
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)