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
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
A oui j'oubliai, j'ai repris le tutorial de ramis pour le compléter par le changement de direction ! merci ramis !
Hors ligne
Bon tutoriel, mais j'ai quelques questions/remarques.
Ben pourquoi il est à True alors ? Faut d'inattention je suppose.
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 :
Enfin, ton code est juste quand même
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
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!
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 |
|
xhtml 1.0 css 2.1 Propulsé par FluxBB Traduit par FluxBB.fr |
882 membres 1429 sujets 11119 messages |
Dernier membre inscrit: LiseBuisson96 33 invités en ligne Aucun membre connecté RSS Feed |