Bonjour tout le monde !
Bon ,je doute que ce soit très utile tellement c'est simple , mais ça pourra peut etre aider les grands débutants comme moi ...
Il s'agit ici , en quelque sorte , de l'adaptation du code de Kevin Leohnart sur les evenements , où il explique comment faire bouger Sydney .
Ici , il s'agit de faire coincider l'animation "courir" de sydney avec le moment où elle (il :-S ? )se déplace . ^^
C'est vraiment , vraiment tout con , et abondamment commenté .
Voilà le code de main.cpp :
#include "CEventReceiver.h" int main(void) { irr::IrrlichtDevice* device = irr::createDevice(irr::video::EDT_OPENGL,irr::core::dimension2d<irr::s32>(640,480),32,false,false,false);//On créé notre device ... irr::video::IVideoDriver* driver = device->getVideoDriver ();//...notre driver ... irr::scene::ISceneManager *sceneManager = device->getSceneManager ();//... et notre scene manager device->getCursorControl ()-> setVisible (false);//vala , c'est plus zoli comme ça , sans curseur :) irr::scene::IAnimatedMeshMD2* modele;//Ici ... modele = (irr::scene::IAnimatedMeshMD2*)sceneManager->getMesh("sydney.md2");//...on charge... irr::scene::IAnimatedMeshSceneNode* Nmodele = sceneManager->addAnimatedMeshSceneNode(modele);//...Sydney ! Nmodele->setMaterialFlag(irr::video::EMF_LIGHTING, false);//On fait en sorte que Sydney ne dépende pas de la lumière (tant mieux , y en a pas) Nmodele->setMaterialTexture( 0, driver->getTexture("sydney.bmp") );//On applique la texture à Sydney irr::scene::ICameraSceneNode *camera;//Ici ... camera = sceneManager->addCameraSceneNodeFPS(0, 100.0f, 300.0f);//...on créé une camera FPS 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 Nmodele->setAnimationSpeed(40); //On définit la vitesse des animations 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) //La boucle de rendu while (device->run()) { 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 ();//On libère la memoire return 0;//et on retourne 0 pour dire que tout s'est bien passé }
celui de CEventReceiver.h :
#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_isMoving;//Un booléen qui indique si on bouge , ou pas };
et CEventReceiver.cpp :
#include "CEventReceiver.h" CEventReceiver::CEventReceiver(irr::scene::IAnimatedMeshSceneNode* Nmodele)//revoilà notre constructeur :) { m_Nmodele = Nmodele;//On pointe le mesh passe en parametre. m_isMoving = false;//Par défaut , le modele est immobile .Donc le booléen qui indique si l'on bouge est à false m_animrun=false;//et comme l'animation n'est du coup pas "courir" , on met notre booléen à false aussi } 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_isMoving = true;//On passe notre booléen "est en train de bouger" à true //Sinon c'est un relachement else m_isMoving = 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 return false; } void CEventReceiver::majPosMesh()//revoilà notre chère fonction de mise à jour de la position { //On verifie que le pointeur vers le mesh est //ok et que la touche est enfoncee if(m_Nmodele != 0 && m_isMoving == true) { //On commence par recuperer la position actuelle irr::core::vector3df v = m_Nmodele->getPosition(); //On y ajoute la valeur de deplacement v.X += 0.5f; //On renvoie la nouvelle position .Sydney va avancer !!! m_Nmodele->setPosition(v); } } void CEventReceiver::majAnimMesh()//Ici , on met à jour l'animation { if(m_Nmodele != 0 && m_isMoving == 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_RUN);//on passe à l'animation "courir" m_animrun=true;//on declare que l'animation courir est bien en trainde se derouler } if(m_Nmodele != 0 && m_isMoving == 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_STAND);//on passe à l'animation "rester en place" m_animrun=false;//et on declare que l'animation courir ne se deroule plus , du coup } }
Voilà .J'imagine (non , je suis sûr ^^) qu'on peut beaucoup optimiser .Mais ça m'a fait un peu pratiquer , au moins ^^, et il y a peut etre une chance pour que ça serve à un autre débutant .
bonne soirée
Merci Ramis, même un tuto simple est un tuto utile. Donc cool d'avoir ajouté cela.
Hors ligne
merci , c'est sympa ^^
vais essayer de l'adapter pour faire un système de déplacement complet (encore un truc inutile ^^ décidément , j'en ai plein la tête )
Hors ligne
bonjour (ou bonsoir lol ) ,
voila, votre code me semble trés utiles pour un noob comme moi qui veut faire bouger son personnage qui est encore dans 3dmax . ... je parle trop,,je suis entrain de modéliser dans 3ds max et je connais absolument pas qu'est ce que je doit faire pour le faire bouger avec les touches clavier dans irrLicht,,, je suis déja le tutorial de Kevin Leonhart sur siteduzero mais en parallèle veuillez m'aider un peu et merci d'avance ...
Hors ligne
salut achoura ,
merci de t'interesser à ce code
Le principe est tout simple en fait :
-Tu met en place ta scène , normalement
-En paralléle ,tu écris une classe CEventReceiver , qui hérite de la classe irr::IEventReceiver .
{Cette classe doit contenir :
-Une méthode constructeur , qui va servir tout simplement à initialiser les attributs de ta classe pour que ton personnage n'avance pas et ne marche pas.
-Une méthode OnEvent , ici en fait , on surcharge la méthode OnEvent de IEventReceiver .Cela va servir , en cas d'évènement(en l'occurence , appui sur Z) , à indiquer que ton personnage marche , à présent .Tout simplement ;o) .Si il n'y a pas d'évenement , on indique que ton personnage ne marche plus .
-Une méthode majPosMesh , qui va servir à mettre à jour la position du mesh .En gros , si on a déclaré que le personnage est en train de marcher dans la méthode OnEvent , on va maintenant le faire avancer régulièrement , en modifiant sa position (pour le faire avancer , il va donc falloir ajouter 1 sur l'axe X , par exemple ).Si le personnage ne marche pas , on ne fait rien .
-Enfin , une méthode majAnimMesh , qui met à jour l'animation du mesh .Celle ci fait deux tests : si le personnage a été déclaré en train de courir dans OnEvent et que son animation n'est pas à "courir" : alors on met son animation à "courir" et on le déclare , grâce à un attribut booléen .Si le personnage n'est pas en train de courir mais que son animation est à "courir" , alors on met son animation à "ne courre pas" et on déclare que l'animation du personnage n'est plus "courir" , dans le même booléen .}
Après cela ,dans la boucle de rendu , il te suffit d'appeller à chaque fois les méthodes majPosMesh et majAnimMesh pour faire les tests à chaque frames et réagir correctement .La méthode OnEvent , étant une surcharge d'une éthode de IEventReceiver , est automatiquement appellée .
Voilà ! J'espère que c'est assez clair .Avec le code , tu devrais y arriver assez bien .Bon courage pour ton projet
Hors ligne
Bonjour, merci à vous pour m'interesser à moi ,,, c moi qui devra remercier .....ok bref j'ai utiliser le code et il est "absolutly good". reste une chose à réviser : les constantes d'animation du modele sydney.md2 (pour tous les modeles md2) comme EMAT_RUN, EMAT_WALK, EMAT_STAND ....... voila comment faire ça dans ma propre personnage .3ds ,, par logique je pense qu'il y a un editeur md2 qui doit importer les modeles 3ds pour ajouter des modifications, j'accepte tous vos propositions et conseilles avec des bras ouvert et merci encore . Fidelement Achoura
Hors ligne
SAlut achoura ,
bah suis content que ça te serve ^^
Pour remplacer les Nmodele->setMD2Animation(EMAT_MACHIN); , tu peux essayer avec Nmodele->setFrameLoop(framededebut, framedefin); .
Ce sera peut etre plus simple à mettre en oeuvre .
Pour l'animation , (je parle toujours en blender ) tu peux , je pense , la faire directement dans le logiciel de modelisation .
Mais c'est pas toujours évident (et moi j'aime pas ) > le principe (je pense que tu le sais déjà ^^) c'est d'armaturer ton modèle (lui mettre un squelette , quoi) pour pouvoir le manipuler simplement , puis de créer ton animation frame par frame , en modifiant la position d'une partie de ton personnage (les jambes par ex , pour un mouvement de marche) .Puis tu exporte ton personnage et tu indique de quelle frame à quelle frame il marche , de quelle frame à quelle frame il saute, etc .
Hors ligne
merci Ramis ,, j'ai mnt une vision plus clair et le flou dans mes yeux commence a devenir plus nette. justement en 3ds max j'utilise une Biped(squelette) pour animer mon caractére et le mettre en vie . je vais travailler un peu mnt sur le projet et je vous metterez à jour dés que possible,,,, @bientôt
Hors ligne
Pages: 1