Historique des modifications - Message

Message #4741

Sujet: lier une animation au deplacement d'un mesh


Type Date Auteur Contenu
Création du message 04-11-2008 19:02:49 ramis
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 smile .

bonne soirée wink

Retour

Options Liens officiels Caractéristiques Statistiques Communauté
Préférences cookies
Corrections
irrlicht
irrklang
irredit
irrxml
Propulsé par Django
xhtml 1.0
css 2.1
884 membres
1440 sujets
11337 messages
Dernier membre inscrit: Saidov17
193 invités en ligne
membre en ligne: -
RSS Feed