Historique des modifications - Message

Message #4741

Sujet: lier une animation au deplacement d'un mesh


TypeDateAuteurContenu
Création du message04-11-2008 19:02:49ramis
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ébutantsmile.

bonne soiréewink

Retour

OptionsLiens officielsCaractéristiquesStatistiquesCommunauté
Préférences cookies
Corrections
irrlicht
irrklang
irredit
irrxml
Propulsé par Django
xhtml 1.0
css 2.1
884 membres
1441 sujets
11339 messages
Dernier membre inscrit: Saidov17
87 invités en ligne
membre en ligne: -
RSS Feed