#25 

14-06-2015 14:13:41

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 907
Corrections: 2
Site web

les variables globales c'est mal, de mon point de vue

tu peut l'écrire de plusieurs façons

Code c++ :


class Something
{
    public:
        Something(int _start, int _end, bool loop = false)
          : start(_start), end(_end)
        {
        }

        Something(int start, int end, bool loop = false)
        {
            this->start = start;
            this->end = end;
        }

        Something(int _start, int _end, bool loop = false)
        {
            start = _start;
            end = _end;
        }
    private:
        int start, end;
};

//et tu l'utilise comme ça ...
Something *tmp = new Something(0, 0); // loop = false
Something *tmp2 = new Something(0, 0, true); // loop = true


la premiere façon permet au compilateur d'optimiser un peut
les deux suivantes sont equivalentes, perso je n'aime pas passer par this
mais c'est peut-être plus explicite si tu commence

par contre c'est a titre d'exmple, tu ne peut évidement avoire plusieurs constructeurs avec les mêmes parametres (et valeurs par default inclue)

par template ça donnerais ceci

Code c++ :

template<int priority, int start, int end, bool loop = false>
class GenericAnimation : public
{
    public:
      virtual void bind()
      {
           NePlayer->setAnimationSpeed(ANIMATION_SPEED);
           NePlayer->setLoopMode(loop);
           NePlayer->setFrameLoop(start,end);
      }
      virtual void unbind()
      {
      }
      virtual int priority()
      {
          return priority
      }
    private:
};

// et utiliser comme ceci
AnimationBinder *tmp = new GenericAnimation<1, 0, 80, true>();
AnimationBinder *tmp = new GenericAnimation<0, 0, 0>();



ça permet surtout d'optimiser un peut, puisque les valeurs sont connue à la compilations, et ne sont jamais stocker en mémoire l'or de l'execution
dans ton cas ce n'est probablement pas nécéssaire

smile

Hors ligne


#26 

14-06-2015 15:28:17

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

ok j'ai compris la théorie, après j'ai essayé et çà ne compile pas sad , j'ai tout plier à mon avis j'aboutirais pas. Merci pour ton aide en tout cas c'est bien sympas smile

Dernière modification par jonath313 (14-06-2015 15:28:44)

Hors ligne


#27 

14-06-2015 15:35:48

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 907
Corrections: 2
Site web

pas de soucis c'est toi qui voie
sinon poste l'erreur de compilation+code et je te dirais ce qui cloche

Hors ligne


#28 

14-06-2015 17:24:34

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

J'ai tenté des choses d'où les commentaires :

Code c++ :


#ifndef CPLAYERANIMATION_H
#define CPLAYERANIMATION_H

#include "irr/irrArray.h"
#include <stdlib.h>
#include <stdio.h>
#include <cstdio>
#include <string>
#include <iostream>
#include <direct.h>
#include <windows.h>
#include <time.h>
#include <cstdlib>
#include <vector>
#include <irr/irrlicht.h>

class AnimationBinder
{
    public:
        virtual void bind() = 0;
        virtual void unbind() = 0;
        virtual int priority() = 0;
       /* virtual int start() = 0;
        virtual int end() = 0;*/


        bool operator < (AnimationBinder *other)
        {
            return priority() < other->priority();
        }

        bool activated;
        bool binded;
       // int start;
       // int end;
};


template<int Apriority, int start, int end, bool loop = false>
class RunningState : public AnimationBinder
{
    public:
        virtual void bind()
        {
           binded = true;
         /*  NePlayer->setAnimationSpeed(ANIMATION_SPEED);
           NePlayer->setLoopMode(true);
           NePlayer->setFrameLoop(0,80);*/

           /*NePlayer->setAnimationSpeed(ANIMATION_SPEED);
           NePlayer->setLoopMode(loop);
           NePlayer->setFrameLoop(start,end);*/

        }
        virtual void unbind()
        {
           binded = false;
          /* NePlayer->setAnimationSpeed(ANIMATION_SPEED);
           NePlayer->setLoopMode(false);
           NePlayer->setFrameLoop(0,0);*/

        }
        virtual int priority()
        {
            return Apriority;
        }

     /*   virtual int start()
        {
            return Apriority;
        }*/

};


class AnimationManager
{
    public:
        AnimationManager(int start, int end, bool loop = false)
        {
           this->start = start;  // ERREUR 1
           this->end = end;


            anim.push_back(new RunningState<1, 0, 80, true>());
            ///...
            anim.sort();
        }
        void activate(int animNumber, bool value)
        {
            auto current = anim[animNumber];
            current->activated = value;

            if(current->binded && !value)
                current->unbind();

            current = anim[0];
            for(std::vector<int>::const_iterator it = anim.start(); it!=anim.end(); ++it) { int current = *it; } // ERREUR 2
           

            if(current->activated && !current->binded)
                current->bind();
        }
    private:
        irr::core::array<AnimationBinder*> anim;
        //int start;
       // int end;
};
#endif // CPLAYERANIMATION_H




C:\Users\Jonathan\Jeu\CPlayerAnimation.h|81|error: 'class AnimationManager' has no member named 'start'|
C:\Users\Jonathan\Jeu\CPlayerAnimation.h|82|error: 'class AnimationManager' has no member named 'end'|


C:\Users\Jonathan\Jeu\CPlayerAnimation.h|98|error: 'class irr::core::array<AnimationBinder*>' has no member named 'start'|
C:\Users\Jonathan\Jeu\CPlayerAnimation.h|98|error: 'class irr::core::array<AnimationBinder*>' has no member named 'end'|

Dernière modification par jonath313 (14-06-2015 17:44:06)

Hors ligne


#29 

14-06-2015 18:12:04

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 907
Corrections: 2
Site web

C:\Users\Jonathan\Jeu\CPlayerAnimation.h|81|error: 'class AnimationManager' has no member named 'start'|
C:\Users\Jonathan\Jeu\CPlayerAnimation.h|82|error: 'class AnimationManager' has no member named 'end'|

tu à commenter les variables
        //int start;
       // int end;

for(std::vector<int>::const_iterator it = anim.start(); it!=anim.end(); ++it) { int current = *it; } // ERREUR 2
anim est un irr::core::array, soit tu utilise std::vector du debut a la fin (donc déclaré std::vector<AnimationBinder*> anim;)
deplus ici ce serait std::vector<AnimationBinder*>::const_iterator, tu doit respecter les types smile
soit tu itère de magnière classique

Hors ligne


#30 

14-06-2015 18:29:56

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

Code c++ :


for( irr::core::array<int>::const_iterator it = anim.start(); it!=anim.end(); ++it) { int current = *it; }



Me donne :
...\CPlayerAnimation.h|99|error: 'const_iterator' is not a member of 'irr::core::array<int>'|
...\CPlayerAnimation.h|99|error: expected ';' before 'it'|
...\CPlayerAnimation.h|99|error: 'it' was not declared in this scope|

Je ne peux pas utiliser "const_iterator" avec un array ?
Et quand il me dit que it n'est pas déclaré c'est parcequ'il ne valide pas le type de la variable ?

ps: J'ai commenté les lignes car ne sais pas si c'est là que je dois y déclarer...

Dernière modification par jonath313 (14-06-2015 18:32:50)

Hors ligne


#31 

14-06-2015 18:59:50

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 907
Corrections: 2
Site web

Et quand il me dit que it n'est pas déclaré c'est parcequ'il ne valide pas le type de la variable ? oui
Je ne peux pas utiliser "const_iterator" avec un array ? non

comme je t'est dit irr::core::array ne posède pas begin() et end(), n'y d'itérateur
donc soit tu itéré de manière classique <<for(int i = 0; i<anim.size(); ++i) ... anim[i]->activated ... etc >>
soit tu utilise std::vector<AnimationBinder*> une bonne fois pour toute, ne mélange pas les types (ici irr::core::array<AnimationBinder*>)
après y a toujours possibilité de "tricher" ... tongue

tu doit effectivement les déclarées de cette façon
public, protected ou private ça dépend de ce que tu as besoin smile

il est important que tu comprenne ces notions, d'où une certaine insistance ^^
bon cependant j'utilise des syntaxes particulière qui ton semer le doute, j'en suite navré

Hors ligne


#32 

14-06-2015 19:28:51

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

Ok je préfére rester sur un territoire connu et itérer de manière classique, j'ai alors modifier le code et là çà compile :

Code c++ :


#ifndef CPLAYERANIMATION_H
#define CPLAYERANIMATION_H

#include "irr/irrArray.h"
#include <stdlib.h>
#include <stdio.h>
#include <cstdio>
#include <string>
#include <iostream>
#include <direct.h>
#include <windows.h>
#include <time.h>
#include <cstdlib>
#include <vector>
#include <irr/irrlicht.h>

class AnimationBinder
{
    public:
        virtual void bind() = 0;
        virtual void unbind() = 0;
        virtual int priority() = 0;

        bool operator < (AnimationBinder *other)
        {
            return priority() < other->priority();
        }

        bool activated;
        bool binded;
};

template<int Apriority, int start, int end, bool loop = false>
class RunningState : public AnimationBinder
{
    public:
        virtual void bind()
        {
           binded = true;
           /*NePlayer->setAnimationSpeed(ANIMATION_SPEED);
           NePlayer->setLoopMode(loop);
           NePlayer->setFrameLoop(start,end);*/

        }
        virtual void unbind()
        {
           binded = false;
          /* NePlayer->setAnimationSpeed(ANIMATION_SPEED);
           NePlayer->setLoopMode(false);
           NePlayer->setFrameLoop(0,0);*/

        }
        virtual int priority()
        {
            return Apriority;
        }

};

class AnimationManager
{
    public:
        AnimationManager(int start, int end, bool loop = false)
        {
            anim.push_back(new RunningState<1, 0, 80, true>());
            ///...
            ///anim.sort();
        }
        void activate(int animNumber, bool value)
        {
            auto current = anim[animNumber];
            current->activated = value;

            if(current->binded && !value)
                current->unbind();

            current = anim[0];

                 for(int i = 0; i<anim.size(); ++i)
                    if(current < anim[i] && anim[i]->activated)
                        current = anim[i];

                    if(current->activated && !current->binded)
                        current->bind();
        }


    private:
         std::vector<AnimationBinder*> anim;

};

#endif // CPLAYERANIMATION_H



Pense tu que ce code est utilisable où j'ai ajouté des erreurs ?

Une autre question me vient à l'éspris, quand tu écris  " anim.sort();" çà signifie quoi concrètement ?

Existe t-il un équivalent de ".sort()" pour les std::vector ???

Deplus, dans la ligne "anim.push_back(new RunningState<1, 0, 80, true>());" , je ne peux pas passer 'start' et 'end' à la place de 0 et 80 çà vient de quoi ?

bon cependant j'utilise des syntaxes particulière qui ton semer le doute, j'en suite navré


Tu n'as pas à être navré, au contraire, tu m'aide beaucoups, grâce à toi je vais enfin pouvoirs comprendre ces notions abstraites smile
Et oui forcément je doute beaucoup sur ce que je fais car pour le moment il faudrait que je comprenne bien avec un type array ou vector pour pouvoirs me dire plus tard que je choisirais l'un ou l'autre. çà me permet de voir aussi que je ne peux pas procéder toujours de la même façon en fonction du type choisit.

Dernière modification par jonath313 (14-06-2015 19:35:30)

Hors ligne


#33 

14-06-2015 19:47:40

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 907
Corrections: 2
Site web

a priori c'est bon, le principe est le même
pour le coup je ne voie pas l'utilité de start, end, loop pour AnimationManager
mais plus tard tu devras passer en paramètre ton "NEPlayer" et le principe est identique

"anim.sort();" c'est pour "rangé" t'est animation par ordre de priorité, non indispensable ici
une optimisation aurais pu ce faire l'or de l'itération par ce biais,
mais franchement c'est ridicule laisse cette aspect pour l'instant
tu peut le remplacer par std::sort(anim.begin(), anim.end())

la différence entre irr::core::array et std::vector ? uhm
irrlicht a coder sont implémentation pour pouvoir être compiler sur des plateformes inaccessible à certaine compilateur (gcc)
aujourd'hui c'est beaucoup moins vrai
les deux sont coder avec le même principe, difficile de te répondre
les performances doivent donc être égale, donc ...

j'espère en tout cas que tu apprécie cette discutions
j'essaye d'être pédagogue, c'est peut-être pas mon fort big_smile

Hors ligne


#34 

14-06-2015 21:22:47

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

Oui j'apprécie cette discussion, le fait que tu persévère dans les explications prouve que tu es pédagogue après oui forcément tu ne peux pas trop utiliser de termes technique dans tes explications car je ne les maîtrises pas donc c'est pas évident pour toi, je comprends bien. En tout cas j'ai le sentiment de m'amélioré mais bon çà prendra le temps qu'il faut smile

Je t'avais aussi demandé pourquoi quand j'écris :

Code c++ :


        AnimationManager(IAnimatedMeshSceneNode* NePlayer,int start, int end, bool loop = false)
        {
            anim.push_back(new RunningState<NePlayer,1, start, end, true>());
///...



Je voudrais passer à RunningState le IAnimatedMeshSceneNode concerné et les frames de début et de fin de l'animation créé, plutôt que de les fixer en dur. Le compilateur n’accepte pas cette opération, certainement que je m'y prends mal. Car sans se passage, je ne peux pas tester si tout cela fonctionne.

||In constructor 'AnimationManager::AnimationManager(irr::scene::IAnimatedMeshSceneNode*, int, int, bool)'neutral
|63|error: could not convert template argument 'NePlayer' to 'irr::scene::IAnimatedMeshSceneNode*'|

Hors ligne


#35 

15-06-2015 00:16:47

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 907
Corrections: 2
Site web

ah ah ! smile

bon en fait c'est tout simple, un template ne peut prendre que des valeurs connue a la compilation
donc un type comme irr::core::array<type> ou std::vector<type>, ...
ou une valeur comme je t'est montré pour RunningState (entier, floatant, enum, ...)

bon mais par contre NePlayer n'est pas connue a la compilation,
ça valeur est plus ou moins aléatoire l'or de sont allocation (adresse mémoire)
tu est donc obliger de passer ce paramètre par le constructeur

Hors ligne


#36 

15-06-2015 18:34:54

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

Là j'ai bien essayé de passer IAnimatedMeshSceneNode* NePlayer au constructeur de AnimationManager. Ok je ne peux pas le passer par le template. j'ai alors fais :

Code c++ :


class RunningState(IAnimatedMeshSceneNode* NePlayer) : public AnimationBinder     ///|34|
{
...
}



Puis :

Code c++ :


class AnimationManager
{
    public:
        AnimationManager(IAnimatedMeshSceneNode* NePlayer,int start, int end, bool loop = false)
        {
            anim.push_back(new RunningState(NePlayer)<1, 0, 80, true>());
        }
...



Donc j'ai voulus passer le IAnimatedMeshSceneNode*  à la classe RunningState. Sois j'ai mal lu sois j'ai mal compris mais çà ne marche pas :

||=== Build: Debug in Jeu (compiler: GNU GCC Compiler) ==neutral

...\CPlayerAnimation.h|34|error: expected ')' before '*' token|
...\CPlayerAnimation.h||In constructor 'AnimationManager::AnimationManager(irr::scene::IAnimatedMeshSceneNode*, int, int, bool)'neutral
C:\Users\Jonathan\Jeu\CPlayerAnimation.h|63|error: invalid use of incomplete type 'class RunningState'|
...\CPlayerAnimation.h|34|error: forward declaration of 'class RunningState'|
...\CPlayerAnimation.h|63|error: expected primary-expression before ')' token|
...\CPlayerAnimation.h||In member function 'void AnimationManager::activate(int, bool)'neutral
...\CPlayerAnimation.h|78|warning: comparison between signed and unsigned integer expressions [-Wsign-compare]|
||=== Build failed: 4 error(s), 2 warning(s) (0 minute(s), 2 second(s)) ==neutral

Hors ligne


#37 

15-06-2015 19:29:13

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 907
Corrections: 2
Site web

mais si ça marche ... juste la syntaxe

Code c++ :

anim.push_back(new RunningState<1, 0, 80, true>(NePlayer));

le templates est toujours indiquer après la classes et avans quoi que ce soit

Hors ligne


#38 

15-06-2015 22:23:09

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

ha oui j'avais pas vue que la parenthèse était après le template, du coups je suis arrivé à un code comme ceci :

Code c++ :


class AnimationBinder
{
    public:
        virtual void bind() = 0;
        virtual void unbind() = 0;
        virtual int priority() = 0;

        bool operator < (AnimationBinder *other)
        {
            return priority() < other->priority();
        }
        bool activated;
        bool binded;
};

class RunningState : public AnimationBinder
{
    public:
        RunningState(IAnimatedMeshSceneNode* NePlayer,int AnimPriority, int FrameStart, int FrameEnd, bool Frameloop = false)
        {
            NodePlayer = NePlayer;
            Apriority = AnimPriority;
            start = FrameStart;
            end = FrameEnd;
            loop = Frameloop;
        }
        virtual void bind()
        {
           binded = true;
           NodePlayer->setAnimationSpeed(50);
           NodePlayer->setLoopMode(loop);
           NodePlayer->setFrameLoop(start,end);
        }
        virtual void unbind()
        {
           binded = false;
           NodePlayer->setAnimationSpeed(50);
           NodePlayer->setLoopMode(false);
           NodePlayer->setFrameLoop(0,0);
        }
        virtual int priority()
        {
            return Apriority;
        }

        IAnimatedMeshSceneNode* NodePlayer;
        int Apriority;
        int start;
        int end;
        bool loop;
};

class AnimationManager
{
    public:
        AnimationManager(IAnimatedMeshSceneNode* NePlayer,int priority,int start, int end, bool loop = false)
        {
            anim.push_back(new RunningState(NePlayer,1,start,end,loop));
        }
        void activate(int animNumber, bool value)
        {
            auto current = anim[animNumber];
            current->activated = value;

            if(current->binded && !value)
                current->unbind();

            current = anim[0];

                 for(int i = 0; i<anim.size(); ++i)
                    if(current < anim[i] && anim[i]->activated)
                        current = anim[i];

                    if(current->activated && !current->binded)
                        current->bind();
        }
    private:
         std::vector<AnimationBinder*> anim;
};
#endif // CPLAYERANIMATION_H



Maintenant pour l'utiliser j'ai déclaré dans ma classe PLAYER :

Code c++ :


    AnimationBinder* machin = new RunningState::RuningState (NePlayer,1,0,80,true);



Le compilateur me dit :
||=== Build: Debug in Jeu (compiler: GNU GCC Compiler) ==neutral
...
||In member function 'void CPlayer::LoadPersoPhysics(irr::video::IVideoDriver*, irr::scene::ISceneManager*, btDiscreteDynamicsWorld*, btAxisSweep3*, int)'neutral
|207|error: expected type-specifier|
|207|error: cannot convert 'int*' to 'AnimationBinder*' in initialization|
|207|error: expected ',' or ';'|
||=== Build failed: 3 error(s), 13 warning(s) (0 minute(s), 2 second(s)) ==neutral

Hors ligne


#39 

15-06-2015 23:41:03

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 907
Corrections: 2
Site web

je t'est déjà répondue pour un probleme similaire (même erreur de compilation) smile
a tu inclue le header (.h) de AnimationManager dans ton header de la class player ?
la définition de la class est obligatoire avans de pouvoire l'utilisé, et n'est jamais établie de manière globale
il te faut résoudre les dépendences directement ou indirectement suivant le contexte

non pour l'utiliser tu passe par AnimationManager
et il n'a pas besoin de (,int priority,int start, int end, bool loop = false)
l'idéal serait que tu les initializes depuis l'animation elle même

que ne comprend tu pas ici ?
tu fait des amalgames ?
que je résolve ça !

bon comme tu as l'aire d'avoire du mal, j'espère que ça t'aideras
perso j'organiserais comme ceci

AnimationBinder.hAnimationManager.hAnimationManager.cppGenericState.hGenericState.cppJumpState.hJumpState.cppPlayer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

class AnimationBinder
{
    public:
        virtual void bind() = 0;
        virtual void unbind() = 0;
        virtual int priority() = 0;

        bool operator < (AnimationBinder *other)
        {
            return priority() < other->priority();
        }

        bool activated;
        bool binded;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

#include "AnimationBinder.h"

enum ANIMATION_STATE
{
     EAS_IDLE,
     EAS_RUNNING,
     EAS_SWIMING,
     ... etc
     EAS_JUMPING,
     EAS_COUNT
};

class AnimationManager
{
    public:
        AnimationManager(IAnimatedMeshSceneNode* NePlayer);
        void activate(int animNumber, bool value);
    private:
         std::vector<AnimationBinder*> anim;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

#include "AnimationManager.h"

#include "GenericState.h"
#include "JumpState.h"

AnimationManager::AnimationManager(IAnimatedMeshSceneNode* NePlayer)
{
       anim.push_back(new GenericState(NePlayer,0,0,0,false)); // idle ?
       anim.push_back(new GenericState(NePlayer,1,0,80,true)); // running ?
       anim.push_back(new GenericState(NePlayer,2,80,160,true)); // swimming ?
       ... etc
       anim.push_back(new JumpState(NePlayer));
}
void AnimationManager::activate(int animNumber, bool value)
{
       auto current = anim[animNumber];
       current->activated = value;

       if(current->binded && !value)
           current->unbind();

       current = anim[0];

       for(int i = 0; i<anim.size(); ++i)
            if(current < anim[i] && anim[i]->activated)
               current = anim[i];

        if(current->activated && !current->binded)
               current->bind();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

#include "AnimationBinder.h"

class GenericState : public AnimationBinder
{
    public:
        GenericState(IAnimatedMeshSceneNode* NePlayer,int AnimPriority, int FrameStart, int FrameEnd, bool Frameloop = false);

        virtual void bind();
        virtual void unbind();
        virtual int priority();

        IAnimatedMeshSceneNode* NodePlayer;
        int Apriority;
        int start;
        int end;
        bool loop;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

GenericState::GenericState(IAnimatedMeshSceneNode* NePlayer,int AnimPriority, int FrameStart, int FrameEnd, bool Frameloop)
{
    NodePlayer = NePlayer;
    Apriority = AnimPriority;
    start = FrameStart;
    end = FrameEnd;
    loop = Frameloop;
}
void GenericState::bind()
{
   binded = true;
   NodePlayer->setAnimationSpeed(50);
   NodePlayer->setLoopMode(loop);
   NodePlayer->setFrameLoop(start,end);
}
void GenericState::unbind()
{
   binded = false;
   NodePlayer->setAnimationSpeed(50);
   NodePlayer->setLoopMode(false);
   NodePlayer->setFrameLoop(0,0);
}
int GenericState::priority()
{
    return Apriority;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

#include "AnimationBinder.h"

class JumpState : public AnimationBinder, public irr::scene::IAnimationEndCallBack
{
    public:
        JumpState(AnimationManager* a, IAnimatedMeshSceneNode* NePlayer);

        virtual void bind();
        virtual void unbind();
        virtual int priority();

        virtual void OnAnimationEnd(IAnimatedMeshSceneNode *node);

        AnimationManager *amgr;
        IAnimatedMeshSceneNode* NodePlayer;
        int Apriority;
        int start;
        int end;
        int state;
        bool loop;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

#include "JumpState.h"

JumpState::JumpState(AnimationManager* a, IAnimatedMeshSceneNode* NePlayer) : state(0), amgr(a)
{
    NodePlayer = NePlayer;
    NodePlayer = NePlayer;
    Apriority = AnimPriority;
    start = FrameStart;
    end = FrameEnd;
    loop = Frameloop;
}
void JumpState::bind()
{
   state = 0;
   NodePlayer->setAnimationEndCallback(this);
   binded = true;
   NodePlayer->setAnimationSpeed(50);
   NodePlayer->setLoopMode(false);
   NodePlayer->setFrameLoop(200,230);
}
void JumpState::unbind()
{
   binded = false;
   NodePlayer->setAnimationSpeed(50);
   NodePlayer->setLoopMode(false);
   NodePlayer->setFrameLoop(0,0);
   NodePlayer->setAnimationEndCallback(0);
}
int JumpState::priority()
{
    return Apriority;
}
void JumpState::OnAnimationEnd(IAnimatedMeshSceneNode *node)
{
      float d = distanceFromGround(node);
      if(d > 0.1f)
      {
          NodePlayer->setLoopMode(true);
          NodePlayer->setFrameLoop(230,270);
      }
      else
      {
          state++;

          if(state == 2)
              amgr->active(EAT_JUMP, false);

          NodePlayer->setLoopMode(false);
          NodePlayer->setFrameLoop(270,300);
      }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Player : public irr::IEventReceiver
{
    public:
      Player()
      {
          loadMesh();
          node = smgr->addAnimatedMeshSceneNode(... blabla)
          anim = new AnimationManager(node);
      }
      ... blabla bla
      virtual bool OnEvent(const irr::SEvent &ev)
      {
          if(event.eventype == irr::quelquechose_JOYSTIC)
          {
              int keys = event.blabla.Sate;
              anim.active(EAS_RUNNING, keys & 0b000001 && onGround);
              anim.active(EAS_SWIMMING, keys & 0b000001 && onWater);
              ... etc
              anim.active(EAS_ATTACKING, keys & 0b001000);
          }
      }
    private:
      AnimationManager *anim;
}



faut pas trop ce prendre la tête
si tu peut faire un nouveaux fichier fait le (header/implementation)
si tu peut gagner en clarté de code fait le aussi
de sorte que la lecture soit "évidente" pour toi (c'est subjectif)

Hors ligne


#40 

16-06-2015 20:46:06

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

Merci pour ton dernier topic, du coups j'ai enfin réussi à harmoniser tout çà. Par contre maintenant çà compile mais il ne se passe rien au niveau de l'animation du player. Le personnage joue toutes les frames d'animation et tout le code est sans effet. (J'ai suivis tout ce que tu m'as dis à la lettre). Quand j'appui sur le bouton concerné il ne se passe rien.

Il manque rien pour contrôler les animations ?

Dernière modification par jonath313 (16-06-2015 22:58:32)

Hors ligne


#41 

17-06-2015 00:46:54

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 907
Corrections: 2
Site web

initialiser activated = binded = false;
dans les constructeurs, autrement ça risque de faire n'importe quoi

normalement c'est bon, peut-être start et end qui sont mal configurer mais ça, sa dépend de t’ont modèle
pareille pour les priorité toi seul le sait

a toi de tracer les fonctions appeler pour savoir ce qui n'est pas appelé

Hors ligne


#42 

17-06-2015 12:37:51

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

Ok, l'initialisation je l'ai faite :

Code c++ :


GenericState::GenericState(IAnimatedMeshSceneNode* NPlayer,int AnimPriority, int FrameStart, int FrameEnd, bool Frameloop)
{
    NodePlayer = NPlayer;
    Apriority = AnimPriority;
    start = FrameStart;
    end = FrameEnd;
    loop = Frameloop;
    activated = binded = false;
}



Les animations IDLE et RUNNING ne se lancent pas. Par contre SWIMMING fonctionne, çà doit provenir de cette partie :

Code c++ :


       anim.push_back(new GenericState(NPlayer,0,1,10,false)); // idle ?
        anim.push_back(new GenericState(NPlayer,1,10,80,true)); // running ?
       anim.push_back(new GenericState(NPlayer,2,80,160,true)); // swimming ?


Si j'utilise que la troisième ligne seule cette animation fonctionne, çà vient du push_back ? (Visiblement c'est la dernière animation qui l'emporte, ce n'est pas une question de priorité d'après ce que j'ai vu)

Ensuite il y a autre chose qui ne va pas et je ne sais pas pourqoi çà fait cela : Si j'appui sur SWIMMING (la seule qui fonctionne), l'animation se joue mais dès que j'appui sur une autre touche, elle se coupe. C'est ennuyeux si je ne peux pas faire tourner la caméra pendant que le personnage avance par exemple:

Code c++ :


if(event.EventType == irr::EET_KEY_INPUT_EVENT ){
animat->activate(EAS_SWIMING, event.KeyInput.Key == irr::KEY_SPACE && event.KeyInput.PressedDown == true & 0b000001); // Fonctionne
animat->activate(EAS_RUNNING, event.KeyInput.Key == irr::KEY_KEY_Z && event.KeyInput.PressedDown == true & 0b000001); // Fonctionne pas
}


Merci pour tas patience.


EDIT: J'ai trouvé la réponse pour le premier probleme (Seule animation SWIMMING), il faut ajouter :

Code c++ :


anim.push_back(new GenericState(NPlayer,0,1,10,false)); // idle ?
...
std::sort(anim.begin(), anim.end());


Pour l'utiliser j'avais juste à ajouter la librairie :

Code c++ :


#include <algorithm>    // std::sort



Après pour le second problème je n'ai pas encore trouvé pourquoi quand j'appui sur une autre touche que celle concerné, çà me stop l'animation.

Dernière modification par jonath313 (17-06-2015 12:56:13)

Hors ligne


#43 

17-06-2015 18:32:27

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 907
Corrections: 2
Site web

Si j'utilise que la troisième ligne seule cette animation fonctionne, çà vient du push_back ? (Visiblement c'est la dernière animation qui l'emporte, ce n'est pas une question de priorité d'après ce que j'ai vu)


euh quoi ? si tu n'a qu'un élément, un seul pourras marcher ...  ?
pas comprit ^^

// Fonctionne // Fonctionne pas


soit plus explicite
c'est celui-ci que tu a résolue ?

Ensuite il y a autre chose qui ne va pas et je ne sais pas pourqoi çà fait cela : Si j'appui sur SWIMMING (la seule qui fonctionne), l'animation se joue mais dès que j'appui sur une autre touche, elle se coupe. C'est ennuyeux si je ne peux pas faire tourner la caméra pendant que le personnage avance par exemple:


peut-être que tu ne fait pas attentions à ce que j'écris, réfléchie un peut plus sur les d'étailles de OnEvent
réfléchie sur la fonction activate, peut-être quelques ajustement, en fonctions de t'est beusoin
peut-être que t'est fonctions unbind sont mal ajuster ?
certaine réponsse ne peuvent venir que de toi

je ne t'est soumit qu'un concept, il est vrai, je ne me suis pas attarder sur les détailles
et je me retrouve à te macher le travaille, bon mais il me semble que tu ne cherche pas beaucoup tout de même hmm

coder par l'intermédiaire d'un forum tu avouras que ce n'est pas pratique
je ne vais pas faire un projet et tout coder moi même ? smile
(quoi que)

Hors ligne


#44 

18-06-2015 15:24:03

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

Oula met toi pas dans cet état...si je te pose des questions c'est parceque ça m'intéresse de comprendre t'as façon de faire. Forcément c'est pas facile mais ne crois pas que je ne cherche pas car je ne suis pas programmeur donc tout ça n'est pas évident pour moi. Et je fais ça pour m'amuser c'est un loisir donc bon le temps que j'y consacre c'est du temps libre. Le fait de coder sur des jeux me permet de m'améliorer sur une de mes faiblesses qui est la programmation.

J'ai réussi à faire fonctionner ce code hier. J'aurai d'autres questions mais je ne veux pas avoir l'impression d'abuser.

En tout cas merci pour ton travail, je serai intéressé de savoir sur quoi tu bosse si tu te sent d'en parler.

Hors ligne


#45 

18-06-2015 18:07:37

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 907
Corrections: 2
Site web

mais non y a pas de soucis
le fait est que tu as pu le faire fonctionner par toit même hier ... donc ce n'était peut-être pas un mal

si tu n'est pas programmeur d'origine, je comprendre certaine chose du coup,
j'aurais dû engager la conversation autrement, tu écris avec une aisance qui m'a trompé

bref, pour les questions tu peut vasy big_smile

je n'est pas pour habitude d'étaler ce que je fait, je trouve que ça fait prétentieux et loin de moi l'idée de vouloir le paraître
il n'y a d'ailleurs, pas beaucoup de trace sur le forum smile

je bosse seul sur un projet de game engine + mmorpg en sample
c'est une sur-couche à irrlicht, il reprend tout les mécanismes de rendue, implémente un systeme d'entité pour remplacer les scenes nodes, gestion des groupes de rendue ...
physique (bullet), sound, network, ... le tout en multi-thread sur le quelle je prépare une thèse
le coeur de l'engine est fonctionelle, il me manque par contre les systeme annexe, particule et IA entre autre
pour l'instant il est en closed source et en standby depuis un certain temps je doit dire à cause des études
(l'ennui fait perdre l'intérêts de la passion)

Hors ligne


#46 

18-06-2015 20:56:53

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

C'est dommage que tu ne mette pas plus en avant ton travail car c'est très interessant. Donc tu fais une thèse, je suppose que tu es un programmeur software, en tout cas on voit que tu connaît bien le domaine car t'as l'air de te débrouiller. J'aurai bien aimé avoir cette autonomie mais bon j'ai choisie l'autre côté de la bestiole informatique, je suis dans le hardware (niveau ingé), donc électronique à donf. Ce que j'ai appris en programmation je l'ai appris seul (je ne compte pas les bases du language C apprises à l'école), les projets sur lesquels je travail sont purement issue des idées personnelles et comme je te l'ai dis précédemment, tout çà c'est un loisir, j'aime essayer de créer des choses par moi-même.

A la base j'ai commencé par apprendre la modélisation 3d et après j'ai tenté l'expérience en alliant mes modeles avec irrlicht. J'ai utilisé irrlicht pour faire plusieurs projets:
- Logiciel d'autocomposition musical (gui irrlicht).
- Une application qui fait bouger un cube sur irrlicht par l'intermédiaire d'un module inertiel que j'ai fabriqué (USB).
- Et en ce moment je reprend un vieux projet de jeux video 2 players.

Pour ma question supplémentaire, je vais rédiger autrement:

-> Le point bloquant concerne vraiment le langage C++ et non la partie Irrlicht.
-> J'ai repris ton code j'ai compris comment il fonctionne, je l'ai implémenté sur mon projet -> tout fonctionne.

Voila, le contexte est énoncé. Enfait, je lance une animation en appuyant sur un bouton, si j'appui sur un autre bouton, une nouvelle animation se lance. Le souci est que si le bouton précédent reste appuyé, l'animation précédente devrait reprendre quand la nouvelle se termine :

Le personnage marche -> je saute (mais le bouton avancer est resté appuyé) -> l'animation sauter est terminé -> Actuellement on unbind sur les frame IDLE qui sont toujours les même.

Donc avant de solliciter ton aide, j'ai analysé ce que je devrais faire:

Plutôt que unbinder sur :

Code c++ :


void GenericState::unbind()
{
   binded = false;
   NodePlayer->setAnimationSpeed(20);
   NodePlayer->setLoopMode(true);
   NodePlayer->setFrameLoop(0,0);
}


Je devrais regarder si une autre animation est active, le cas échéant, lancer l'animation IDLE. çà implique un fonctionnement "inter-classe" si je puis me permettre d'appeler çà comme çà. Peut être que çà ne vient pas de là non-plus, je peux me planter, mais c'est une idée à laquelle j'ai réfléchie. Au niveau algorythmique çà donnerai :

Code c++ :


void GenericState::unbind()
{
   binded = false;
   Si une animation est active on la joue
   Sinon on joue l'animation IDLE
}



Sauf si le fait de lancer une nouvelle animation désactive la précédente hmm et dans ce cas mon idée est fausse. Si c'est çà, je pourrais peut-être avoir un booleen d'activation représentatif par animation ?

Si mon idée n'est pas fausse, ce que je ne sais pas faire, c'est la partie algorythmique énoncé ci dessus, car je ne sais pas si je dois utiliser des pointeurs, enfin c'est un peut le brouillon et j'ai pas envie de faire du bricolage sans comprendre vraiment comment il faudrait que je m'y prenne.

Merci pour ton aide et pour ton soutient smile

Hors ligne


#47 

18-06-2015 22:09:25

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 907
Corrections: 2
Site web

uhm uhm smile
merci pour ce long post, avec de bonne explication et constructif ça fait plaisir

Enfait, je lance une animation en appuyant sur un bouton, si j'appui sur un autre bouton, une nouvelle animation se lance. Le souci est que si le bouton précédent reste appuyé, l'animation précédente devrait reprendre quand la nouvelle se termine :


très bien dans ce cas, j'en conclue que soit tu as un soucis avec la gestions de évènement (point #1)
soit unbind interfère totalement avec le fonctionnement voulue, et donc tu as raison sur ce que tu explique (point #2)

pour le point #1:
je te met les deux codes

Code c++ :


          if(event.eventype == irr::quelquechose_JOYSTIC)
          {
              int keys = event.blabla.State;
              anim.active(EAS_RUNNING, keys & 0b000001 && onGround);
              anim.active(EAS_SWIMMING, keys & 0b000001 && onWater);
              ... etc
              anim.active(EAS_ATTACKING, keys & 0b001000);
          }


Code c++ :


if(event.EventType == irr::EET_KEY_INPUT_EVENT ){
animat->activate(EAS_SWIMING, event.KeyInput.Key == irr::KEY_SPACE && event.KeyInput.PressedDown == true & 0b000001); // Fonctionne
animat->activate(EAS_RUNNING, event.KeyInput.Key == irr::KEY_KEY_Z && event.KeyInput.PressedDown == true & 0b000001); // Fonctionne pas
}


voila quelle est la grosse différence ?
et bien déjà je passe par le joystick et donc comme tu l'avais demander dans un autre topic
event.blabla.State détermine l'état des boutons, et leurs états reste actif tout au long de l’appuie (bit 1 boutton 1, bit 2 ... etc)
et donc quand je fait anim.active(EAS_RUNNING, keys & 0b000001 && onGround) le resultat ne change pas si une autre touche est impliquer
en ce qui concerne "&0b00001" c'est une simple opération binnaire que tu a recopier un peut "bêtement", ici "event.blabla.State" est un entier
en electronique tu utilise la même chose avec les portes "AND", donc keys & 0b00001 détermine si le bit 1 est a 1 c'est tout

tu comprendra aussi que dans ton code "&0b000001" est inutile ? true = 1 et "1 & 0b000001 = 1" c'est l'opération que tu fait !

or toi tu test sur event.KeyInput.Key, c'est un entier représentant une énumeration, donc une seul valeurs possible, pour preuve tu fait un test d'égalité
donc comme tu fait, l'un va s'activer, puis l'autre jamais les deux en même temps, logique ...
ce que tu doit faire donc c'est un truc du genre:

Code c++ :


if(event.EventType == irr::EET_KEY_INPUT_EVENT ){
    if(event.KeyInput.Key == irr::KEY_SPACE)
        animat->activate(EAS_SWIMING, event.KeyInput.PressedDown);
    if(event.KeyInput.Key == irr::KEY_KEY_Z)
        animat->activate(EAS_RUNNING, event.KeyInput.PressedDown);
}



donc pour le point #2:

Je devrais regarder si une autre animation est active, le cas échéant, lancer l'animation IDLE. çà implique un fonctionnement "inter-classe" si je puis me permettre d'appeler çà comme çà. Peut être que çà ne vient pas de là non-plus, je peux me planter, mais c'est une idée à laquelle j'ai réfléchie. Au niveau algorythmique çà donnerai :


oui tu as raison, mais dans ce cas, j'opterais simplement pour ne rien mettre dans unbind (excepter binded = false), et pour l'animation "IDLE" avoir une classe personnaliser
puisque effectivement lorsque tu fait des opération sur "NePlayer" elle désactive la précédente animation

Code c++ :

class IdleState : public AnimationBinder
{
    public:
        IdleState()
        {
            activated = true;
            bind();
        }
        virtual void bind()
        ... etc
        virtual int priority()
        {
            return -99;
        }
};


pourquoi ? et bien déjà par ce que si aucune animation est active, celle-ci le resteras, et donc ce binderas en dernier
et finalement unbind ne réalisais que l'appelle a idle donc inutile

bon par contre je voie un autre soucis, c'est si tu utilise une animation en loop = false
que ce passe t'il lorsque l'animation ce finie ? ba rien, elle est toujours considéré comme active, donc comment le régler ?
barf, tu peut simplement faire une classes qui dérive de irr::scene::IAnimationEndCallBack, tu passe AnimationManager en temps que pointeur dans la constructeur de tas nouvelle class
tu le stock et dans OnAnimationEnd tu desactive ton animation, tu peut regarder JumpState comme exemple, je te laisse bidouiller un peut (ça te feras un peut d'exercice ... )
puis bon si tout fois tu n'y arrive pas je passerais voir ce qu'il en est

edit/ps:
bon par contre, tu fait de l'électronique, j'en est fait durant mais études, je vais voir quelle genre d'analogie je peut faire
mais honnêtement je n'en voie pas une grosse différence avec la programmations surtout quand on ce raproche des micro-controlleur & porte logique & module

Dernière modification par Magun (18-06-2015 22:14:40)

Hors ligne


#48 

18-06-2015 23:57:27

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

Ok merci pour ces précisions. J'ai essayé de faire avec une classe IdleState, je n'y suis pas arrivé, j'y ais passé la soirée. Je me permet de te poser une question pour savoir si ce qui va suivre est une solution ...

Est-ce que je peux Passer le AnimationManager* à GenericState ?

En ajoutant une fonction à la classe AnimationManager du genre :

Code c++ :


int getCurrentActiveAnimation()
{
       auto current = anim[animNumber];
       current->activated = value;
       return  value;
}



Cette fonction me permettrait de savoir en continue laquelle est active, après je ferais quelque chose du genre :

Code c++ :


GenericState::GenericState( AnimationManager* a, IAnimatedMeshSceneNode* NPlayer)
{
    NodePlayer = NPlayer;
...
    amgr = a;
}

...

void GenericState::unbind()
{
   binded = false;
   int ActiveAnimation = amgr -> getCurrentActiveAnimation();

   switch(ActiveAnimation )
   {
     case 0: //IDLE
       /// On joue les frames idle
     break;

     case 1: //RUNNING
       /// On joue les frames courrir
     break;
   }
   ...
    default:
       /// On joue les frames idle
     break;
}



A chaque relâchement d'un bouton il y a binded = false, à partir de ce moment il est possible de savoir quand l'animation à jouer doit être déterminée. Après je suis tétu, je te l'accorde. Mais si cette solution n'est pas fonctionnelle, dis moi pourquoi stp...

Bon du coups on code sur un forum smile mais d'un côté çà me permet d'échanger en live sur les points qui me bloques, encore une foi je te pose une question qui concerne surtout le language "objet" (car en électronique on ne fait pas d'objet :p).

Merci.

EDIT: Je viens de penser à quelque chose. Dis moi si je me trompe mais c'est encore une mauvaise idée car au moment du unbind() l'animation active sera celle qu'on jouait et pas la restante non ? (çà va partir en discours philosophique ...)

Dernière modification par jonath313 (19-06-2015 00:00:31)

Hors ligne


#49 

19-06-2015 11:06:11

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 907
Corrections: 2
Site web

Est-ce que je peux Passer le AnimationManager* à GenericState ?


biensur comme tu a fait, c'est bon
tu peut envoyer ce que tu veut

Code c++ :


int getCurrentActiveAnimation()
{
       auto current = anim[animNumber];
       current->activated = value;
       return  value;
}

je ne suis pas convaincue, puisque déjà il peut y avoir plusieurs animation active, mais une seul de "binder"
et puis généralement un getter n'oppère pas de modifications, bon ça à la rigueur ...

bon ensuite en ce qui concerne ton unbind ce que tu fait reviens à

Code c++ :


void GenericState::unbind()
{
   binded = false;
   int ActiveAnimation = amgr -> getCurrentActiveAnimation();
   amgr->active(ActiveAnimation, amgr->anim[ActiveAnimation].activated);
}


or unbind est déjà appeller par amgr->activated(..), donc tu tourne en rond pour faire la même chose qui ce produit plus haut
et donc (activated = false)

Code c++ :


void GenericState::unbind()
{
   binded = false;
   if(activated) bind();
   else unbind();
}



je vais essyer d'être encore plus claire

Code c++ :


void AnimationManager::activate(int animNumber, bool value)
{
       auto current = anim[animNumber];
       // ici on active ou desactive l'animation visé
       current->activated = value;

       // si c'était une animation prioritaire et quelle n'est plus active on n'arrete de la jouer
       if(current->binded && !value)
           current->unbind();

       current = anim[0];

       // on recherche l'animation active aillent la plus grosse prioriter et active
       for(int i = 0; i<anim.size(); ++i)
            if(current < anim[i] && anim[i]->activated)
               current = anim[i];

        // si une animation est trouver c'est quelle est prioritaire et active
        // si elle n'est pas jouer alors on la joue
        if(current->activated && !current->binded)
              current->bind();
}



donc admeton que tu est 3 animation, idle, run, attack
idle est toujours active de plus faible prioriter, sans suit run et attack

si tu active run, c'est la plus forte prioriter elle ce joue
si tu active attack, c'est la plus forte prioriter elle ce joue (run est toujours activer)
si tu desactive run, rien ne ce passe attack est toujours la plus forte
si tu desactive attack, idle deviens la plus forte prioriter, elle ce joue

la fonctions bind nottify l'état "jouer l'animation" et unbind par "arreter de l'animation" ...
"binded" correspond a l'état, l'animation est en "lecture"
mais si tu arrete une animation, c'est qu'une autre va en prendre la place

c'est pas plus compilquer que ça
pour le reste, j'en reviens a mon poste précédent

Hors ligne


Options Liens officiels Caractéristiques Statistiques Communauté
Corrections
irrlicht
irrklang
irredit
irrxml
xhtml 1.0
css 2.1
Propulsé par FluxBB
Traduit par FluxBB.fr
881 membres
1426 sujets
11116 messages
Dernier membre inscrit: Bidule
22 invités en ligne
Aucun membre connecté
RSS Feed