#0 

20-02-2009 00:16:11

NeoCrysis
Membre
Date d'inscription: 20-02-2009
Messages: 11

----------------------------
RESOLU, merci Capry wink
----(solution en bas)-----

Bonjour (c'est mon premier message, je me suis retenu le plus possible je vous assure !),

Je fais appel à vous car j'ai un problème (et oui sinon je ne posterai pas xD) :
- Cela fait X temps (2 jours plus ou moins) que je ne parviens pas à faire bouger ma petite Sydney (fox ?) comme il le faudrait, elle ne suit pas la direction de ma souris, si je regarde au nord-est et que j'appuie sur la touche avancer, ça ira tout droit et non au nord-est.

Je sais que cette question à déjà été posée et que vous devez en avoir raz la casquette de voir défiler des débutants en quete du FPS fabuleux, mais ce n'est pas mon cas, je veux apprendre et ce problème est un frein à mon imagination ^^.

Ca fait 3 jours que j'utilise Irrlicht (avant je faisais du PHP/JS/C++/Qt), donc c'est tout nouveau, je ne me suis pas encore bien familiarisé avec ce merveilleux outil wink
Ce qui veut dire aussi que mon code est surement mal fichu et faux, mais je vous le donne quand même smile (Il fonctionne parfaitement à l'heure actuelle)

main.cpp (utile ?..)

Code:

int main(void)
{
    Demo demo(false);
    demo.initWorld();
    demo.initPerso();
    demo.initCamera();
    demo.initLumiere();

    demo.startGame();

    return 0;
}

demo.h

Code:

#ifndef H_DEMO
#define H_DEMO

#include "FollowingCamera.h"
#include <irr/irrlicht.h>

class Demo
{
public :
    Demo(bool fullscreenc);
    ~Demo();
    void initWorld(); // Initialisation de l'environnement
    void initPerso(); // Initialisation des acteurs
    void initCamera(); // Initialisation de la camera
    void initLumiere(); // Initialisation de la lumière
    void initKeys(); // Initialisation des commandes
    void startGame(); // Lancement du jeu
    void changeView();
    bool cam_thirdPerson;
    //virtual bool OnEvent(const SEvent& event);
    IrrlichtDevice* device;
    irr::scene::IAnimatedMeshSceneNode* Nmodele;
    FollowingCamera* MaCamera;
    ITriangleSelector* selector;
    ITriangleSelector* selector2;

    ITerrainSceneNode* terrain;

private :
    bool fullscreen;

    scene::ICameraSceneNode* camera;
    video::IVideoDriver* driver;
    scene::ISceneManager *sceneManager;

    scene::IAnimatedMesh *room;
    ISceneNode* q3node;
    ISceneNode* q3node2;

    irr::scene::IAnimatedMeshMD2* modele;

    scene::ILightSceneNode* lumiere;

    irr::SKeyMap keyMap[5];


};
#endif

demo.cpp

Code:

#include "Demo.h"
#include "CEventReceiver.h"
#include "FollowingCamera.h"
#include <iostream>

using namespace irr;
using namespace std;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

Demo::Demo(bool f)
: fullscreen(f)
{
    cam_thirdPerson = true; // Vue 1ère personne (false) | 3ème personne (true)
}

Demo::~Demo() { }

void Demo::initWorld()
{
    //Device, driver et graphe de scene

    device = irr::createDevice(video::EDT_OPENGL,
    core::dimension2d<s32>(800,600),32,fullscreen,false,false);

    driver = device->getVideoDriver ();
    sceneManager = device->getSceneManager ();

    //On rend invisible le curseur
    device->getCursorControl ()-> setVisible (true);
    ICursorControl* myCursor = device->getCursorControl();

    device->getFileSystem()->addZipFileArchive("map-20kdm2.pk3");
    room = sceneManager->getMesh("20kdm2.bsp");

    if(cam_thirdPerson) {
        // COLLISION CAMERA
        q3node = 0;
        if (room)
            q3node = sceneManager->addOctTreeSceneNode(room->getMesh(0));
        selector = 0;
        if (q3node)
        {
            q3node->setPosition(vector3df(-1370,-130,-1400));
            selector = sceneManager->createOctTreeTriangleSelector(room->getMesh(0), q3node, 128);
            q3node->setTriangleSelector(selector);
            selector->drop();
        }
    }
    if (room == 0)
    {
        std::cout << "--> Probleme de chargement de la salle" << std::endl;
    }

}

void Demo::startGame() {

    CEventReceiver receiver(Nmodele);
    device->setEventReceiver(&receiver);

    while (device->run())
    {
        sceneManager->getActiveCamera();
        driver->beginScene(true, true, video::SColor(0,200,200,200));

        if(cam_thirdPerson) {
            if(MaCamera) {MaCamera->Update();}
            receiver.majPosMesh(*MaCamera->getCam(), true);
        } else {
            receiver.majPosMesh(*camera);
            Nmodele->setRotation(vector3df(0,(camera->getRotation().Y - 90),0)); // Ne bouge que de gauche à droite le perso
        }

        sceneManager->drawAll ();
        driver->endScene ();
    }

    device->drop ();
}

void Demo::initPerso() {

    //Sydney
    modele = (irr::scene::IAnimatedMeshMD2*)sceneManager->getMesh("sydney.md2");
    Nmodele = sceneManager->addAnimatedMeshSceneNode(modele);

    if(Nmodele) {
        //On modifie les proprietes de Sydney
        Nmodele->setMaterialFlag(irr::video::EMF_LIGHTING, false);
        Nmodele->setFrameLoop(0, 0);
        Nmodele->setMaterialTexture( 0, driver->getTexture("sydney.bmp") );

        Nmodele->setPosition(vector3df(0,0,0));
        Nmodele->setRotation(vector3df(0,0,0)); // dos a la camera
    }
    // COLLISION PERSONNAGE
    q3node2 = 0;
    if (room)
        q3node2 = sceneManager->addOctTreeSceneNode(room->getMesh(0));
    selector2 = 0;

    if (q3node2)
    {
        q3node2->setPosition(vector3df(-1370,-130,-1400));
        selector2 = sceneManager->createOctTreeTriangleSelector(room->getMesh(0), q3node2, 128);
        q3node2->setTriangleSelector(selector2);
        selector2->drop();
    }

    ISceneNodeAnimator* CollisionCamera = sceneManager->createCollisionResponseAnimator(
    selector2, Nmodele, core::vector3df(10,30,10),
    vector3df(0,0,0),
    vector3df(0,0,0));
    Nmodele->addAnimator(CollisionCamera);
    CollisionCamera->drop();


}

void Demo::initCamera() {
    //La camera
    if(cam_thirdPerson) {
        MaCamera = new FollowingCamera(Nmodele, sceneManager,
                                                      true,           // Pour utiliser une position initiale.
                                                      selector,       // Pour les collisions.
                                                      100,            // Distance.
                                                      50,             // Hauteur.
                                                      30,             // Delta cible.
                                                      vector3df(-50,200,-120));   // Position initiale.
        sceneManager->setActiveCamera( MaCamera->getCam() );
    } else {
        if(camera=sceneManager->addCameraSceneNodeFPS (0, 100.0f, 300.0f, -1, false, 5, false, 0.4)) {
            cout << "--> Camera chargee" << endl;
            //camera->setPosition(vector3df(0,20,-30));
            //camera->setParent(Nmodele);
            camera->setPosition(vector3df(0,0,0)  + core::vector3df(0,25,0));
            camera->setRotation(vector3df(0,90,0));
        }
        else
            cout << "--> Erreur lors du chargement de la camera" << endl;
    }

}

void Demo::initLumiere() {
/*
    if(lumiere = sceneManager->addLightSceneNode(Nmodele, core::vector3df(150,210,250),video::SColorf(0.4f, 0.4f, 0.4f, 0.4f), 30.0f))
        cout << "--> Lumiere ambiante ok" << endl;
    else
        cout << "--> Erreur lors du chargement de la lumiere ambiante" << endl;
*/
}

void Demo::changeView() {
    cam_thirdPerson = true;
}

Comme vous pouvez le constater j'utilise la classe FollowingCamera (pour avoir la vue à la 3ème personne), mais c'est juste pour tester, elle ne sert strictement à rien wink

Pendant ces deux jours j'ai essayé tout et n'importe quoi et je suis à bout ...
Si quelqu'un  pouvait me donner un indice, ça m'aiderait énormément.

Cordialement moi smile

Dernière modification par NeoCrysis (20-02-2009 12:43:07)

Hors ligne


#1 

20-02-2009 11:51:56

capry
Membre
Date d'inscription: 14-02-2009
Messages: 83

Je ne vois pas l'endroit où tu définit les touches.
Dans le .h il y a bien une fonction "void initKeys()" mais tu ne la définie pas dans le .cpp .
Sinon pour faire la camera qui suit le perso je ne pense pas que tu t'y prennes bien, je pencherai plutot pour faire un truc comme ça (je peux me tromper) :
-> création du modèle (appelons le noeud "Nmodele")
-> création de la caméra FPS (appelons-là "camera")
-> dans la boucle de rendu on met : " camera->setTarget(Nmodele); " et positionne la camera derrière le perso;
-> puis on crée une classe d'évenements qui gère l'appuie d'une touche pour avancer (ou reculer) et qui va changer la rotation de "m_Nmodele" (que l'on passera en argument pour le constructeur de la classe) de -.1 quand la souris va à gauche et .1 quand la souris va à droite.

Je fais ça au réveil donc je peux peut-être faire une énorme erreur, mais si tu as besoin du code je peux te le donner si tu veux...

Hors ligne


#2 

20-02-2009 12:02:22

NeoCrysis
Membre
Date d'inscription: 20-02-2009
Messages: 11

EDIT : Il semblerait que j'ai trouvé une solution (un code que j'ai trouvé sur siteduzero.com), si ça fonctionne bien, je posterai mon code smile (ne pas tenir compte de la suite)

Merci de m'avoir répondu Capry smile
J'ai effectivement la fonction initKeys, que j'ai supprimé dans le .cpp car que je la laisse ou je la supprime je pouvais toujours bouger. (une bourde ?)
J'ai bien compris ton idée mais un petit bout de code me rassurerai smile

Je viens de voir que je n'ai pas donné tout le code !
Voici le CEventReceiver.cpp (et .h) manquant : (c'est de la grosse bidouille, je n'ai pas cherché à optimiser en faisant des boucles ou des tableaux pour les touches, j'ai fais au plus simple)
CEventReceiver.cpp

Code:

#include "CEventReceiver.h"
#include "Demo.h"
#include <iostream>

using namespace std;
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

CEventReceiver::CEventReceiver(scene::IAnimatedMeshSceneNode* Nmodele)
{
    cout << "--> Construction evenement" << endl;
    //On pointe le mesh passe en parametre.
    m_Nmodele = Nmodele;
    //Par defaut on ne bouge pas
    m_isMoving = false;
}


bool CEventReceiver::OnEvent(const irr::SEvent &event)
{

    if(m_Nmodele != 0 && event.EventType == irr::EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown == true)
    { // Recherche de la touche associee
        if(m_isMoving == false) {
            switch(event.KeyInput.Key) {
                case irr::KEY_KEY_Z:
                    touche = irr::KEY_KEY_Z;
                    break;
                case irr::KEY_KEY_S:
                    touche = irr::KEY_KEY_S;
                    break;
                case irr::KEY_KEY_Q:
                    touche = irr::KEY_KEY_Q;
                    break;
                case irr::KEY_KEY_D:
                    touche = irr::KEY_KEY_D;
                    break;
                case irr::KEY_SPACE:
                    touche = irr::KEY_SPACE;
                    break;
                case irr::KEY_CONTROL:
                    touche = irr::KEY_CONTROL;
                    break;
                default:;
            }
            m_isMoving = true; // Mouvement detecte
        }
        return true;
    }
    // Event non traite
    return false;

}


void CEventReceiver::majPosMesh(irr::scene::ICameraSceneNode &camera, bool thirdPerson)
{
    if(m_Nmodele != 0 && m_isMoving == true)
    { // Mouvement en cours
        core::vector3df v = m_Nmodele->getPosition(); // Recuperation position actuelle
        switch(touche) { // Valeur deplacement
            case irr::KEY_KEY_Z:
                v.X += 2.0f;
                break;
            case irr::KEY_KEY_S:
                v.X -= 2.0f;
                break;
            case irr::KEY_KEY_D:
                v.Z -= 2.0f;
                break;
            case irr::KEY_KEY_Q:
                v.Z += 2.0f;
                break;
            case irr::KEY_SPACE:
                v.Y += 5.0f;
                break;
            case irr::KEY_CONTROL:
                v.Y -= 5.0f;
                break;
            default:;
        }
        m_isMoving = false;
        core::vector3df direction = m_Nmodele->getRotation().rotationToDirection(v);
        //m_Nmodele->setPosition(m_Nmodele->getPosition() + direction);
        m_Nmodele->setPosition(v); // On renvoie la nouvelle position
        if(!thirdPerson)
            camera.setPosition(m_Nmodele->getPosition() + core::vector3df(0,25,0));

        cout << "Mouvement" << endl;
    }

}

CEventReceiver.h

Code:

#ifndef H_EVENT
#define H_EVENT

#include <irr/irrlicht.h>
#include "Demo.h"
class CEventReceiver : public irr::IEventReceiver
{

public :

    //Le constructeur.
    CEventReceiver(irr::scene::IAnimatedMeshSceneNode* Nmodele);
    //Capte automatiquement les events.
    bool OnEvent(const irr::SEvent &event);
    //Met a jour la position du mesh.
    void majPosMesh(irr::scene::ICameraSceneNode &camera, bool thirdPerson = false);

private :

    //Le modele qu'on va controler.
    irr::scene::IAnimatedMeshSceneNode* m_Nmodele;
    char touche;
    //Indique si on est deja en mouvement ou pas.
    bool m_isMoving;

};
#endif

Dernière modification par NeoCrysis (20-02-2009 12:24:23)

Hors ligne


#3 

20-02-2009 12:40:55

NeoCrysis
Membre
Date d'inscription: 20-02-2009
Messages: 11

Voila le seul élèment que j'ai modifié :
CEventReceiver.cpp

Code:

void CEventReceiver::majPosMesh(irr::scene::ICameraSceneNode &camera, bool thirdPerson)
{
    if(m_Nmodele != 0 && m_isMoving == true)
    { // Mouvement en cours

        core::vector3df c = m_Nmodele->getPosition(); // Position du modele
        core::vector3df d = m_Nmodele->getRotation(); // Rotation du modele
        float diry = ((d.Y+90)*3.14)/180;
        if (touche == irr::KEY_KEY_Z) // Si on veut avancer
        {
            c.X += speed * cos((d.Y) * 3.14 / 180);
            c.Z -= speed * sin((d.Y) * 3.14 / 180);
        }
        if (touche == irr::KEY_KEY_S) // Si on veut reculer
        {
            c.X -= speed * cos((d.Y) * 3.14 / 180);
            c.Z += speed * sin((d.Y) * 3.14 / 180);
        }
        if (touche == irr::KEY_KEY_Q) // Si on va a gauche
        {
            //d.Y -= 0.1;
            c.Z += speed * cos((d.Y) * 3.14 / 180);
            c.X += speed * sin((d.Y) * 3.14 / 180);
        }
        if (touche == irr::KEY_KEY_D) // Si on va a droite
        {
            //d.Y += 0.1;
            c.Z -= speed * cos((d.Y) * 3.14 / 180);
            c.X -= speed * sin((d.Y) * 3.14 / 180);
        }

        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);
        m_isMoving = false;
        if(!thirdPerson)
            camera.setPosition(m_Nmodele->getPosition() + core::vector3df(0,25,0));
    }
}

Tous les mouvements fonctionnent ainsi (avancer,reculer,gauche,droite selon la position du curseur de la souris).
Merci Capry, je risque de revenir bientôt pour d'autres problèmes ^^

Bonne journée wink

Hors ligne


#4 

20-02-2009 14:16:03

capry
Membre
Date d'inscription: 14-02-2009
Messages: 83

Aucun problème ^^. Moi aussi j'ai des problèmes avec la caméra...

Hors ligne


#5 

20-02-2009 14:40:33

NeoCrysis
Membre
Date d'inscription: 20-02-2009
Messages: 11

Ah, je ne pense pas être la meilleure personne pour t'aider wink

J'ai viré la 3ème personne, je me concentre sur l'utile !
J'ai éclaircis un peu le code, je reposte si jamais ça interesse des débutants qui auront autant merdouillé que moi ^^

Ne pas tenir compte de la fonction pour avoir Sydney qui court, c'est en cours ...

CEventReceiver.h

Code:

#ifndef H_EVENT
#define H_EVENT

#include <irr/irrlicht.h>
#include "Demo.h"
class CEventReceiver : public irr::IEventReceiver
{

public :

    //Le constructeur.
    CEventReceiver(irr::scene::IAnimatedMeshSceneNode* Nmodele);
    //Capte automatiquement les events.
    bool OnEvent(const irr::SEvent &event);
    //Met a jour la position du mesh.
    void majPosMesh(irr::scene::ICameraSceneNode &camera);
    void majAnimMesh(); //On met à jour l'animation du mesh , si besoin est

private :

    //Le modele qu'on va controler.
    irr::scene::IAnimatedMeshSceneNode* m_Nmodele;
    char touche;
    //Indique si on est deja en mouvement ou pas.
    bool m_isMoving;
    bool m_animrun;

    struct SCamKeyMap
            {
                SCamKeyMap() {};
                SCamKeyMap(s32 a, EKEY_CODE k) : action(a), keycode(k) {}
                s32 action;
                EKEY_CODE keycode;
            };
    core::array<SCamKeyMap> KeyMap;
    bool CursorKeys[6];

};
#endif

CEventReceiver.cpp

Code:

#include "CEventReceiver.h"
#include "Demo.h"
#include <iostream>

using namespace std;
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

int speed = 5;

CEventReceiver::CEventReceiver(scene::IAnimatedMeshSceneNode* Nmodele)
{
    cout << "--> Construction evenement" << endl;
    //On pointe le mesh passe en parametre.
    m_Nmodele = Nmodele;
    //Par defaut on ne bouge pas
    m_isMoving = false;
    m_animrun = false;

    KeyMap.push_back(SCamKeyMap(0, irr::KEY_KEY_Z));
    KeyMap.push_back(SCamKeyMap(1, irr::KEY_KEY_S));
    KeyMap.push_back(SCamKeyMap(2, irr::KEY_KEY_Q));
    KeyMap.push_back(SCamKeyMap(3, irr::KEY_KEY_D));
    KeyMap.push_back(SCamKeyMap(4, irr::KEY_SPACE));
    KeyMap.push_back(SCamKeyMap(5, irr::KEY_CONTROL));
    KeyMap.push_back(SCamKeyMap(6, irr::KEY_ESCAPE));
}


bool CEventReceiver::OnEvent(const irr::SEvent &event)
{
    if(m_Nmodele != 0 && event.EventType == irr::EET_KEY_INPUT_EVENT)
    { // Recherche de la touche associee

        s32 cnt = (s32)KeyMap.size(); // nombre de touches enregistrees
        for (s32 i=0; i<cnt; ++i)
            if (KeyMap[i].keycode == event.KeyInput.Key) // si la touche est enregistree
            {
                CursorKeys[KeyMap[i].action] = event.KeyInput.PressedDown; // on enregistre la pression
                m_isMoving = true; // mouvement detecte
                return event.KeyInput.PressedDown; // on renvoie la pression
            }
        return false;
    } else
        return false;
}


void CEventReceiver::majPosMesh(irr::scene::ICameraSceneNode &camera)
{
    if(m_Nmodele != 0 && m_isMoving == true)
    { // Mouvement en cours

        core::vector3df c = m_Nmodele->getPosition(); // Position du modele
        core::vector3df d = m_Nmodele->getRotation(); // Rotation du modele
        float diry = ((d.Y+90)*3.14)/180;

        if (CursorKeys[0]) // Si on veut avancer
        {
            c.X += speed * cos((d.Y) * 3.14 / 180);
            c.Z -= speed * sin((d.Y) * 3.14 / 180);
        }
        if (CursorKeys[1]) // Si on veut reculer
        {
            c.X -= speed * cos((d.Y) * 3.14 / 180);
            c.Z += speed * sin((d.Y) * 3.14 / 180);
        }
        if (CursorKeys[2]) // Si on va a gauche
        {
            //d.Y -= 0.1;
            c.Z += speed * cos((d.Y) * 3.14 / 180);
            c.X += speed * sin((d.Y) * 3.14 / 180);
        }
        if (CursorKeys[3]) // Si on va a droite
        {
            //d.Y += 0.1;
            c.Z -= speed * cos((d.Y) * 3.14 / 180);
            c.X -= speed * sin((d.Y) * 3.14 / 180);
        }
        if (CursorKeys[4]) // Si on veut monter
        {
            c.Y += 5.0f;
        }
        if (CursorKeys[5]) // Si on veut monter
        {
            c.Y -= 5.0f;
        }

        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);

        m_isMoving = false;
        //camera.setPosition(m_Nmodele->getPosition() + core::vector3df(0,25,0));
    }
}

void CEventReceiver::majAnimMesh()//Ici , on met à jour l'animation
{
    cout << "m_isMoving="<< m_isMoving << " || m_animrun="<< m_animrun << endl;
    if(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_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
    }
}

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
882 membres
1429 sujets
11119 messages
Dernier membre inscrit: LiseBuisson96
33 invités en ligne
Aucun membre connecté
RSS Feed