Historique des modifications - Message

Message #11779

Sujet: Séquenceur d'animation de personnage


Type Date Auteur Contenu
Création du message 19-03-2017 22:30:21 Magun
Salut, alors jvais un peut tout décortiquer, et je te donne mes impréssions à "vif"

tous tes define pour configurer l'animation d'un perso, pourquoi pas, quid de la configuration dynamique ?
comment tu fait avec différent modèles, tu fait un header a chaque fois et tu recompile ?
sur un gros projet tu augmente considérablement le temps de dev (puisque conflit de versionning sur repo)

#define RESET 0
#define SET 1

  • > "pas bien", tu essaye de masquer l'utilisation d'un type de base, ici les valeurs true et false d'un boolean

en terme de lecture par un tier et donc de maintanance c'est "moche"
et comme ça complique la lecture, ça complique aussi l'analyse et les symplification logique que tu peut apportés au code (donc optimisation)

ce qui m'amène à la première fonction @keypad_KEY_SAVED_STATE_control
peut facilement ce réécrire

Code c++ :

void keypad_KEY_SAVED_STATE_control(uint8_t AskingState, irr::EKEY_CODE key)
{
    if(KEY_SAVED_STATE[key] != AskingState)
        KEY_SAVED_STATE[key] = AskingState;
}


et donc

Code c++ :

void keypad_KEY_SAVED_STATE_control(uint8_t AskingState, irr::EKEY_CODE key)
{
    KEY_SAVED_STATE[key] = AskingState;
}


et donc la fonction devient inutile
en passant le keyword static, est ici inutile, a la rigeur inline serait plus approprié smile

même remarque pour @key_event_test
finalement ça ce simplifi par:

Code c++ :

void key_event_test(const SEvent& event)
{
    keypad_KEY_SAVED_STATE_control(event.KeyInput.PressedDown, event.KeyInput.Key);
}


ou encore en supprimant l'appelle de la fonction keypad_KEY_SAVED_STATE_control:

Code c++ :

void key_event_test(const SEvent& event)
{
    KEY_SAVED_STATE[event.KeyInput.Key] = event.KeyInput.PressedDown;
}

finalement key_event_test n'est pas vraiment utile en soit
du coup même remarque pour OnEvent

Code c++ :

    bool OnEvent(const SEvent& event)
    {
        if(event.EventType == irr::EET_KEY_INPUT_EVENT)
            KEY_SAVED_STATE[event.KeyInput.Key] = event.KeyInput.PressedDown;
        return false;
    }

donc en gros, évite les fonctions qui n'apporte pas de l'isibilité a ton code,
quand tu écris une fonction, pose toi la question si elle donne:
  • plus de "sens" au "flux" d'execution de ton code
  • une meilleurs compréhension globale et/ou locale


  • ------------------------------------------------------


voila pour le début, j'en arrive au système d'animation
première remarque, une classe serais la bienvenu pour la compréhension
ça n'apporte pas grand chose en terme de performance certe,
mais quand même plus simple à lire,
puisque cela exclue les segments de code telque l'initialisation quand on cherche une info

la fonction @fsm_goNextState n'apporte pas une meilleur compréhension
tu peut simplement l'enlever, l'appelle d'une fonction à un cout:
15 à 30 cycle cpu contre 1 cycle pour une affectation



ensuite, on ne comprend pas bien pourquoi tu as 2 fonctions
qui peuvent être syntétiser en seulement une fonction,
@animation_bind_single et @animation_bind_loop
sans parler des paramètres à ralonge (cf première remarque du post)
et donc, pourquoi ne pas faire une structure de donner ?

dans un premier temp tu défini les informations dans un header
ensuite, tu n'a plus cas modifier PlayerAnimationSetting en pointeur
et charger les informations par exemple a partir d'un xml ...
et c'est plus facile a lire

Code c++ :

struct AnimationSetting
{
    unsigned int start;
    unsigned int end;
    unsigned int speed;
    bool loop;
};

enum ANIMATION_TYPE
{
    EAT_WAIT = 0,
    EAT_IDLE,
    EAT_WALK,
    EAT_JUMP,
    EAT_ATTACK,
    EAT_BACKJP,
    EAT_TAKE,
    EAT_GIVE,
    
    EAT_COUNT
};

static const PlayerAnimationSetting[] = {
    {184, 184,  0, false}, // EAT_WAIT
    {184, 205,  4, true},  // EAT_IDLE
    {  1,  12, 10, true},  // ...
    { 94, 102, 10, false}, // etc
    { 32,  44, 10, false},
    {146, 158, 10, false},
    { 32,  38, 20, false},
    { 38,  44, 20, false}  // EAT_GIVE
};

et donc:

Code c++ :

void animation_bind(EKEY_CODE key, ANIMATION_TYPE a, uint8_t newState)
{
    if(KEY_SAVED_STATE[key])
    {
        anim_working = !pas.loop;
        // pas sur d'avoir compris ton histoire de "anim_working = true" dans un cas et pas dans l'autre
        const AnimationSetting &pas = PlayerAnimationSetting[a];
        NodePlayer->setAnimationSpeed(pas.speed);
        NodePlayer->setFrameLoop(pas.start, pas.end);
        NodePlayer->setLoopMode(pas.loop);
        next_state = newState;
    }
}


bref @animation_bind_idle ne me semble pas tout à fait juste
pour les raison évoquer dans mon précédent poste, que faire si une autre touche est toujours active ?

pour @animation_bind_ended donc je reviens à IAnimationEndCallBack,
pas sur de l'utilité de setLoopMode(false) ici, à tester sens
du coup avec IAnimationEndCallBack cette fonction est inutile tout comme le comptage des frames
@frameEnCour et (NodePlayer->getFrameNr())> (new_anim_end - ANIM_OFFSET), ... etc

Code c++ :

void animation_bind_ended(ANIMATION_TYPE a)
{
  const AnimationSetting &anim = PlayerAnimationSetting[EAT_WAIT];
  if((NodePlayer->getFrameNr())> (anim.end - ANIM_OFFSET))
  {
      anim_working = false;
      NodePlayer->setLoopMode(false);
  }
}


pour @animation_bind_idle
ça devient juste:

Code c++ :

void animation_bind_idle(EKEY_CODE key)
{
    if(!KEY_SAVED_STATE[key] && anim_working == false)
    {
        const AnimationSetting &idle = PlayerAnimationSetting[EAT_WAIT];
        NodePlayer->setAnimationSpeed(idle.speed);
        NodePlayer->setFrameLoop(idle.start, idle.end);
        NodePlayer->setLoopMode(idle.loop);
        next_state = ST_IDLE_0;
    }
}

qui doit probablement pouvoir être fusioné avec @animation_bind

  • ----------------------------------------


pour la dernière fonctions il suffi de remplacer ...

Code c++ :

void fsm_perso_manage_anim(void)
{
    /// On relève le numero de la frame en cours
    frameEnCour = NodePlayer->getFrameNr();

    switch(state)
    {
        case ST_IDLE_0:
            animation_bind(KEY_ATTK, EAT_ATTACK, ST_ATTAK_3);
            animation_bind(KEY_JUMP, EAT_JUMP, ST_JUMP_2);
            animation_bind(KEY_TAKE, EAT_TAKE, ST_TAKE_4);
            animation_bind(KEY_GIVE, EAT_GIVE, ST_GIVE_5);
            animation_bind(KEY_WALK, EAT_WALK, ST_WALK_1);
            break;
        case ST_WALK_1:
            animation_bind(KEY_ATTK, EAT_ATTACK, ST_ATTAK_3);
            animation_bind(KEY_JUMP, EAT_JUMP, ST_JUMP_2);
            animation_bind_idle(KEY_WALK);
            break;
        case ST_JUMP_2:
            animation_bind_ended(EAT_JUMP);
            animation_bind_idle(KEY_JUMP);
            break;
        case ST_ATTAK_3:
            animation_bind_ended(EAT_ATTACK);
            animation_bind_idle(KEY_ATTK);
            break;
        case ST_TAKE_4:
            animation_bind_ended(EAT_TAKE);
            if(NodeBox)NodePlayer->addChild(NodeBox);
            NodeBox -> setScale(vector3df(0.1f,0.1f,0.1f));
            NodeBox -> setPosition(vector3df(0.0f,-0.1f,0.0f));
            animation_bind_idle(KEY_TAKE);
            break;
        case ST_GIVE_5:
            animation_bind_ended(EAT_GIVE);
            if(NodeBox)NodeTerrain -> addChild(NodeBox);
            if(NodeBox)NodePlayer->removeChild(NodeBox);
            NodeBox -> setScale(vector3df(0.5f,0.5f,0.5f));
            NodeBox -> setPosition(vector3df(0.0f,10.1f,0.0f));
            animation_bind_idle(KEY_GIVE);
            break;
        default :
            break;
    }
    state = next_state;
}

a noter qu'il y a equivalence entre les etats et les animation, on pourrais n'en garder qu'un
ST_GIVE_5 == EAT_GIVE, ... etc

je te laisse méditer sur cela wink
cordialemnt Magun

Retour

Options Liens officiels Caractéristiques Statistiques Communauté
Préférences cookies
Corrections
irrlicht
irrklang
irredit
irrxml
Propulsé par Django
xhtml 1.0
css 2.1
884 membres
1440 sujets
11337 messages
Dernier membre inscrit: Saidov17
161 invités en ligne
membre en ligne: -
RSS Feed