#0 

26-01-2010 20:32:29

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

Tenez les ptits gars je suis généreux je vous donne mon travail qui a monopolisé mon petit cerveau de graphiste pour m'orienter vers la programmation.
  Ce code sert au déplacement d'un personnage à la troisiéme personne et autorise le déplacement avant, arrière, droite et gauche dans la direction où le personnage s'auriente, en utilisant l'animation marcher.

Il est constitué de 3 fichier :

     - 1 main
     - 1 CEventReceiver.cpp
     - 1 CEventReceiver.h


CEventReceiver.hCEventReceiver.cppmain.cpp
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 <irrlicht.h>

//Les namespaces nous évitent d'avoir toujours à recopier le parent de la classe qu'on appelle .Je sais , c'est pas bien ...
using namespace irr;
using namespace core;
using namespace gui;
using namespace video;
using namespace scene;

class CEventReceiver : public irr::IEventReceiver//On créé une classe CEventReceiver , fille de la classe IEventReceiver
{

public ://dans la partie publique , on va mettre les prototypes de nos fonctions

    CEventReceiver(irr::scene::IAnimatedMeshSceneNode* Nmodele);//On créé le constructeur , qui prend en parametre le node de notre modele(ici , Sydney , donc)
    virtual bool OnEvent(const irr::SEvent &event);//Cette fonction est lancée en cas d'évenement
    void majPosMesh();//On met à jour la position de notre mesh
    void majAnimMesh();//On met à jour l'animation du mesh , si besoin est

private ://dans la partie privée , on met nos attributs

    irr::scene::IAnimatedMeshSceneNode* m_Nmodele;//Le node que l'on va manipuler
    bool m_animrun;//Un booléen qui indique si l'animation du personnage est "courir"(EMAT_RUN) , ou pas
    bool m_isAvance;//Un booléen qui indique si on bouge , ou pas
    bool m_isRecule;
    bool m_isDroite;
    bool m_isGauche;
    bool m_isSauter;
};
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143


#include "CEventReceiver.h"

CEventReceiver::CEventReceiver(irr::scene::IAnimatedMeshSceneNode* Nmodele)//revoilà notre constructeur :)
{
    m_Nmodele = Nmodele;//On pointe le mesh passe en parametre.
    m_isAvance = false;//Par défaut , le modele est immobile .Donc le booléen qui indique si l'on bouge est à false
    m_animrun=true;//et comme l'animation n'est du coup pas "courir" , on met notre booléen à false aussi
    m_isRecule=false;
    m_isDroite=false;
    m_isGauche=false;
    m_isSauter=false;
}


bool CEventReceiver::OnEvent(const irr::SEvent &event)//En cas d'évenement :
{
    //On verifie que le pointeur est ok
    if(m_Nmodele != 0
    //Qu'il s'agit d'un event concernant un appui/relachement de touche
    && event.EventType == irr::EET_KEY_INPUT_EVENT
    //Qu'il s'agit bien de la touche z
    && event.KeyInput.Key == irr::KEY_KEY_Z)
    {
        //Si il s'agit d'un appui
        if(event.KeyInput.PressedDown == true)
            m_isAvance = true;//On passe notre booléen "est en train de bouger" à true


        //Sinon c'est un relachement
        else
            m_isAvance = false;//Donc , comme on doit s'arrêter , on met ce même booléen à false
        //L'event est traite, on retourne true
        return true;
    }
    //Si on arrive la, c'est qu'on a pas traite l'event , donc on retourne false

  if(m_Nmodele != 0  && event.EventType == irr::EET_KEY_INPUT_EVENT && event.KeyInput.Key == irr::KEY_KEY_S)
    {
        if(event.KeyInput.PressedDown == true)
            m_isRecule = true;
        else
            m_isRecule = false;
        return true;
    }
    //Si on arrive la, c'est qu'on a pas traite l'event , donc on retourne false

    if(m_Nmodele != 0  && event.EventType == irr::EET_KEY_INPUT_EVENT && event.KeyInput.Key == irr::KEY_KEY_D)
    {
        if(event.KeyInput.PressedDown == true)
            m_isDroite = true;
        else
            m_isDroite = false;
        return true;
    }
    //Si on arrive la, c'est qu'on a pas traite l'event , donc on retourne false

    if(m_Nmodele != 0  && event.EventType == irr::EET_KEY_INPUT_EVENT && event.KeyInput.Key == irr::KEY_KEY_Q)
    {
        if(event.KeyInput.PressedDown == true)
            m_isGauche = true;
        else
            m_isGauche = false;
        return true;
    }
    //Si on arrive la, c'est qu'on a pas traite l'event , donc on retourne false

        if(m_Nmodele != 0  && event.EventType == irr::EET_KEY_INPUT_EVENT && event.KeyInput.Key == irr::KEY_SPACE)
    {
        if(event.KeyInput.PressedDown == true)
            m_isSauter = true;
        else
            m_isSauter = false;
        return true;
    }
    //Si on arrive la, c'est qu'on a pas traite l'event , donc on retourne false
    return false;
}


void CEventReceiver::majPosMesh()//revoilà notre chère fonction de mise à jour de la position
{
   
core::vector3df c =m_Nmodele->getPosition();
core::vector3df d= m_Nmodele->getRotation();
float diry = ((d.Y+90)*3.14)/180;
int speed=1;

    //On verifie que le pointeur vers le mesh est
    //ok et que la touche est enfoncee
    if(m_Nmodele != 0 && m_isAvance == true)
    {
         c.X += speed * cos((d.Y) * 3.14 / 180);
         c.Z -= speed * sin((d.Y) * 3.14 / 180);
    }

    if(m_Nmodele != 0 && m_isRecule == true)
    {
        c.X -= speed * cos((d.Y) * 3.14 / 180);
        c.Z += speed * sin((d.Y) * 3.14 / 180);
    }

    if(m_Nmodele != 0 && m_isDroite == true)
    {
        d.Y += 0.1;
    }

    if(m_Nmodele != 0 && m_isGauche == true)
    {
        d.Y -= 0.1;
    }

    if(m_Nmodele != 0 && m_isSauter == true)
    {
        c.Y += 5.1;
    }

     m_Nmodele->setRotation(d);
    int xf = (c.X-sin(diry)*125);
    int yf =(c.Z-cos(diry)*125);
    int zf =100;

    m_Nmodele->setPosition(c);

}

void CEventReceiver::majAnimMesh()//Ici , on met à jour l'animation
{
    if(m_Nmodele != 0 && m_isAvance == true && m_animrun ==false)    //Si le pointeur vers le mesh est ok , si l'on bouge et si l'on n'a pas encore mis à jour l'animation ...
    {
        m_Nmodele->setMD2Animation(EMAT_STAND);//on passe à l'animation "courir"
        m_Nmodele->setFrameLoop(1,44);
        m_Nmodele->setAnimationSpeed(80);
        m_animrun=true;//on declare que l'animation courir est bien en trainde se derouler
    }
        if(m_Nmodele != 0 && m_isAvance == false && m_animrun ==true)    //Si le pointeur vers le mesh est ok , si l'on ne bouge plus et si l'on n'a pas encore mis à jour l'animation ...
    {
        m_Nmodele->setMD2Animation(EMAT_RUN);//on passe à l'animation "rester en place"
        m_animrun=false;//et on declare que l'animation courir ne se deroule plus , du coup
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23


...
Nmodele->setMD2Animation(EMAT_STAND);//A l'origine , Sydney est immobile : on lance donc l'animation EMAT_STAND (l'animation où Sydney ne bouge pas , donc)

CEventReceiver receiver(Nmodele);//On créé un objet instance de la classe CEventReceiver : c'est notre capteur d'évènements
device->setEventReceiver(&receiver);//on définit cet objet comme le capteur pour notre device

...

   while (device->run())                                // la boucle de rendu
    {
        driver->beginScene(true,true,
        irr::video::SColor(0,200,200,200));
        receiver.majPosMesh();//a chaque frame , on appelle la fonction qui met à jour la position du Mesh
        receiver.majAnimMesh();//a chaque frame , on appelle la fonction qui , si besoin est  , modifie l'animation du mesh
        sceneManager->drawAll ();
        driver->endScene ();
    }

    device->drop ();
    return 0;
}


voila il demande à être optimisé car je suis seulement débutant dans la programmation ... J'aimerais avoir vos avis svp merci :)

Hors ligne


#1 

27-01-2010 00:20:57

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

A oui j'oubliai, j'ai repris le tutorial de ramis pour le compléter par le changement de direction ! merci ramis !

Hors ligne


#2 

27-01-2010 10:56:35

Hawk
Membre
Lieu: Wissous
Date d'inscription: 08-11-2008
Messages: 91
Site web

Bon tutoriel, mais j'ai quelques questions/remarques.

Code c++ :


m_animrun=true;//et comme l'animation n'est du coup pas "courir" , on met notre booléen à false aussi


Ben pourquoi il est à True alors ? Faut d'inattention je suppose.

Code c++ :


if(m_Nmodele != 0 && m_isAvance == true)
    {
         c.X += speed * cos((d.Y) * 3.14 / 180);
         c.Z -= speed * sin((d.Y) * 3.14 / 180);
    }

    if(m_Nmodele != 0 && m_isRecule == true)
    {
        c.X -= speed * cos((d.Y) * 3.14 / 180);
        c.Z += speed * sin((d.Y) * 3.14 / 180);
    }



Là, il y a une petite optimisation à faire. Juste avant, tu a calculé diry qui est en fait d.Y en degré + 90°
or cos( a + 90) = - sin (a)
et sin (a + 90) = cos (a)

Donc cos (d.Y) = sin (diry)
et sin (d.Y) = - cos (diry)
(le tout en degré)

Du coup, ton code devient :

Code c++ :


if(m_Nmodele != 0 && m_isAvance == true)
    {
         c.X += speed * sin(diry);
         c.Z -= speed * - cos(diry));
    }

    if(m_Nmodele != 0 && m_isRecule == true)
    {
        c.X -= speed * sin(diry);
        c.Z += speed * -cos(diry);
    }


Enfin, ton code est juste quand même smile

Code c++ :


     m_Nmodele->setRotation(d);
    int xf = (c.X-sin(diry)*125);
    int yf = (c.Z-cos(diry)*125);
    int zf =100;

    m_Nmodele->setPosition(c);



Là, j'ai l'impression que tu calcules un x, un y et un z que tu n'utilises pas . A quoi servent-ils ?

Hors ligne


#3 

27-01-2010 13:07:26

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

Dans mes dernière modif j'ai échangé EMAT_STAND et EMAT_RUN car la condition était à corriger :

m_Nmodele->setMD2Animation(EMAT_STAND);//on passe à l'animation "courir"

m_Nmodele->setMD2Animation(EMAT_RUN);//on arréte

Cependant je suis un vieu flémard c'est pour cela que j'ai pas changé les commentaires! wink

Effectivement tes améliorations sont juste mais bon pourquoi faire simple quand on peut faire compliqué ! non enfait c'est que j'ai posté ce code dès qu'il a été fonctionnel alors je ne l'ais pas optimisé directement.

Pour les variables qui ne servent à rien, effectivement elle servent à rien ... ce code à besoin d'être réorganisé et mis au propre car je suis un peu bordélique.

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
12 invités en ligne
Aucun membre connecté
RSS Feed