#0 

03-07-2012 18:41:49

jeandu65200
Petit nouveau
Date d'inscription: 03-07-2012
Messages: 6

Bonjour ,

Je suis en train de développer en mini FPS et j'ai un problème avec la fonction "s'accroupir" , je ne sais pas comment m'y prendre . J'ai essayé createFlyStraightAnimator mais apparemment ça ne marche pas . Est-ce que vous pouvez me mettre sur la piste ?

Merci d'avance smile

Hors ligne


#1 

03-07-2012 20:29:00

johnplayer
Habitué
Date d'inscription: 30-09-2007
Messages: 431

Comme ça, je dirais qu'il faut capter l'événement du bouton affecté à la fonction "s'accroupir". Je suppose que tu as mis un animator de collision donc il faut voir s'il y a possibilité de modifier la collision en hauteur. La solution la plus propre serait de créer ta propre cameraFPS en reprenant le code d'irrlicht et en y ajoutant la création de la collision à la création de la camera et la fonction "s'accroupir" dans la KeyMap et en implémentant l'action associée. L'implémentation de la camera est dans "source/CSceneNodeAnimatorCameraFPS.cpp". Pour la keymap et l'enum KEY_ACTION, c'est dans "include/SKeyMap.h". Soit tu modifies le code source d'Irrlicht (ce que je ne ferais pas car c'est à refaire si tu changes de version entre temps), soit tu copies (en changeant les noms de fichier, de classe et d'enum) les fichiers "source/CSceneNodeAnimatorCameraFPS.cpp et .h" et "include/SKeyMap.h".

1/ ajouter EKA_ACCROUPIR à EKEY_ACTION;
2/ ajouter dans le constructeur "KeyMap.push_back(SKeyMap(EKA_ACCROUPIR, irr::KEY_LSHIFT));" (j'ai mis LSHIFT pour l'exemple mais tu mets ce que tu veux);
3/ dans "CSceneNodeAnimatorCameraFPS::animateNode(...)" tu as :

Code:

if (CursorKeys[EKA_JUMP_UP])
    {
        const ISceneNodeAnimatorList& animators = camera->getAnimators();
        ISceneNodeAnimatorList::ConstIterator it = animators.begin();
        while(it != animators.end())
        {
            if(ESNAT_COLLISION_RESPONSE == (*it)->getType())
            {
                ISceneNodeAnimatorCollisionResponse * collisionResponse =
                    static_cast<ISceneNodeAnimatorCollisionResponse *>(*it);

                if(!collisionResponse->isFalling())
                    collisionResponse->jump(JumpSpeed);
            }

            it++;
        }
    }

Inspires t'en pour pour savoir comment accéder à l'animateur de collision et implémenter :
if (CursorKeys[EKA_ACCROUPIR])
{
     /// change la hauteur de l'ellipse avec ISceneNodeAnimatorCollisionResponse::setEllipsoidTranslation();
}

J'espère avoir été assez clair, je viens juste de regarder les sources donc c'est plus une piste qu'une solution. En tout cas, le principe est là.


core i7 4970K @ 4GHz - 32GB ddr3 19200(2400MHz) - ssd samsung 840 evo 250GB - GTX1080Ti (4K) - Cooler master storm stryker blanc.
"L'alcool, c'est comme Activia, c'est actif à l'intérieur et ça se voit à l'extérieur."

Hors ligne


#2 

03-07-2012 21:17:26

jeandu65200
Petit nouveau
Date d'inscription: 03-07-2012
Messages: 6

Salut smile

Merci pour ta réponse rapide et clair , je m'y met tout de suite wink

Par contre je ne comprends pas quand tu dis de changer la hauteur de l'ellipse avec ISceneNodeAnimatorCollisionResponse::setEllipsoidTranslation(); , pourrais tu plus m'éclairer à ce sujet ? C'est avec ça qu'on pourra s'accroupir ?

Merci d'avance big_smile

Hors ligne


#3 

03-07-2012 22:07:28

johnplayer
Habitué
Date d'inscription: 30-09-2007
Messages: 431

Comme le nom de la fonction l'indique, elle sert à faire translater l'animateur de collision. Si tu changes la valeur de Y dans setEllipsoidTranslation( vector3df(X, Y, Z) ), tu vas faire "coulisser" la collision selon Y et donc ta camera se lèvera ou s'abaissera en conséquence. Maintenant, je n'ai pas essayé donc je ne peux te le garantir mais je pense que ça marchera correctement.

Pour mieux expliquer :
Tu prends setEllipsoidRadius(vector3df(30, 20, 30)).
Si tu as : setEllipsoidTranslation( vector3df(0, 0, 0) ) ton node camera est à 30 du sol (EllipsoidRadius : X et Z donne la hauteur et Y le tour du personnage)
maintenant si tu as : setEllipsoidTranslation( vector3df(0, -50, 0) ) ton node camera est à 30 + 50 du sol car tu as translater de 50 vers le bas ta collision qui a elle-même un rayon de 30 donc ton node est maintenant à 80 du sol.
En fait quand tu décales ta collision ta caméra n'est plus au centre de la collision donc faire aussi attention au comportement.

D'ailleurs utilise plutôt setEllipsoidRadius et tu modifies X et Z en même temps et avec les mêmes valeurs pour modifier la hauteur de collision.

D'ailleurs faut aussi prévoir une fonction pour le remettre debout ton joueur^^.

Dernière modification par johnplayer (03-07-2012 22:12:56)


core i7 4970K @ 4GHz - 32GB ddr3 19200(2400MHz) - ssd samsung 840 evo 250GB - GTX1080Ti (4K) - Cooler master storm stryker blanc.
"L'alcool, c'est comme Activia, c'est actif à l'intérieur et ça se voit à l'extérieur."

Hors ligne


#4 

06-07-2012 17:03:38

jeandu65200
Petit nouveau
Date d'inscription: 03-07-2012
Messages: 6

Salut smile

Merci pour ces précisions , je comprend mieux comment ça marche à présent wink. Pour l'instant j'ai décidé de recompiler Irrlicht pour changer le code source mais je me retrouve confronté a un autre problème , quand je déclare dans le main :

keyMap[10].Action = irr::EKA_ACCROUPIR;
keyMap[10].KeyCode = irr::KEY_LSHIFT;

Et que je compile , Code::Blocks me met comme erreur : error : 'EKA_ACCROUPIR' is not member of 'irr' .

J'ai bien pris le soin de tout recompiler Irrlicht et de reprendre la bilbiothèque statique dans le SDK/lib

Je ne sais pas comment y remédiez , Merci d'avance smile

Cordialement.

Hors ligne


#5 

06-07-2012 17:26:32

johnplayer
Habitué
Date d'inscription: 30-09-2007
Messages: 431

As-tu déclaré EKA_ACCROUPIR dans l'enum EKEY_ACTION?

Dans include/SKeyMap.h,  tu dois avoir :

Code:

// Copyright (C) 2002-2011 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h

#ifndef __S_KEY_MAP_H_INCLUDED__
#define __S_KEY_MAP_H_INCLUDED__

#include "Keycodes.h"

namespace irr
{

    //! enumeration for key actions. Used for example in the FPS Camera.
    enum EKEY_ACTION
    {
        EKA_MOVE_FORWARD = 0,
        EKA_MOVE_BACKWARD,
        EKA_STRAFE_LEFT,
        EKA_STRAFE_RIGHT,
        EKA_JUMP_UP,
        EKA_CROUCH,
        EKA_ACCROUPIR,  /////////////////////////////////////////////////    LIGNE A AJOUTER ABSOLUMENT AVANT EKA_COUNT
        EKA_COUNT,

        //! This value is not used. It only forces this enumeration to compile in 32 bit.
        EKA_FORCE_32BIT = 0x7fffffff
    };

    //! Struct storing which key belongs to which action.
    struct SKeyMap
    {
        SKeyMap() {}
        SKeyMap(EKEY_ACTION action, EKEY_CODE keyCode) : Action(action), KeyCode(keyCode) {}

        EKEY_ACTION Action;
        EKEY_CODE KeyCode;
    };

} // end namespace irr

#endif

J'ai marqué la ligne que tu es censé avoir ajoutée avec "/////////////////////////////////////////////////    LIGNE A AJOUTER ABSOLUMENT AVANT EKA_COUNT".


core i7 4970K @ 4GHz - 32GB ddr3 19200(2400MHz) - ssd samsung 840 evo 250GB - GTX1080Ti (4K) - Cooler master storm stryker blanc.
"L'alcool, c'est comme Activia, c'est actif à l'intérieur et ça se voit à l'extérieur."

Hors ligne


#6 

06-07-2012 18:23:51

jeandu65200
Petit nouveau
Date d'inscription: 03-07-2012
Messages: 6

Oui ,j'ai bien rajouter la ligne EKA_ACCROUPIR juste avant EKA_COUNT et ça me met la même erreur , bizarre sad c'est peut être un problème de lib ou je ne sais quoi oO

Hors ligne


#7 

06-07-2012 19:50:10

johnplayer
Habitué
Date d'inscription: 30-09-2007
Messages: 431

J'allais te dire une connerie^^. Je ne vois pas de quoi ça peut venir. Essai de remplacer EKA_ACCROUPIR par EKA_MOVE_FORWARD pour voir, toujours en gardant le irr:: bien sûr.
Au fait, j'avais pas vu mais tu mets "keyMap[10].Action = irr::EKA_ACCROUPIR; keyMap[10].KeyCode = irr::KEY_LSHIFT; " dans le main?! Tant qu'à modifier les sources mets ton code dans "CSceneNodeAnimatorCameraFPS.cpp".

Dans "CSceneNodeAnimatorCameraFPS.cpp", tu as :

Code:

    // create key map
    if (!keyMapArray || !keyMapSize)
    {
        // create default key map
        KeyMap.push_back(SKeyMap(EKA_MOVE_FORWARD, irr::KEY_UP));
        KeyMap.push_back(SKeyMap(EKA_MOVE_BACKWARD, irr::KEY_DOWN));
        KeyMap.push_back(SKeyMap(EKA_STRAFE_LEFT, irr::KEY_LEFT));
        KeyMap.push_back(SKeyMap(EKA_STRAFE_RIGHT, irr::KEY_RIGHT));
        KeyMap.push_back(SKeyMap(EKA_JUMP_UP, irr::KEY_KEY_J));
        KeyMap.push_back(SKeyMap(EKA_ACCROUPIR, irr::KEY_LSHIFT)); ////////////// c'est ici qu'il faut ajouter la ligne
    }

Toutes les modifications que tu veux apporter à la caméra seront dans "CSceneNodeAnimatorCameraFPS.h" et "CSceneNodeAnimatorCameraFPS.cpp".

Dernière modification par johnplayer (06-07-2012 20:40:44)


core i7 4970K @ 4GHz - 32GB ddr3 19200(2400MHz) - ssd samsung 840 evo 250GB - GTX1080Ti (4K) - Cooler master storm stryker blanc.
"L'alcool, c'est comme Activia, c'est actif à l'intérieur et ça se voit à l'extérieur."

Hors ligne


#8 

06-07-2012 20:47:39

jeandu65200
Petit nouveau
Date d'inscription: 03-07-2012
Messages: 6

Oui j'ai déjà mis cette ligne ( KeyMap.push_back(SKeyMap(EKA_ACCROUPIR, irr::KEY_LSHIFT)); ) tu me la dis dans ton premier post et j'avais déjà EKA_MOVE_FORWARD ça marchait . Moi je pense plutôt que le projet ne tiens pas compte de la modification du code source d'Irrlicht , après je sais pas trop faut voir ^^

Dernière modification par jeandu65200 (06-07-2012 20:49:20)

Hors ligne


#9 

06-07-2012 21:25:27

johnplayer
Habitué
Date d'inscription: 30-09-2007
Messages: 431

Quand tu créés ta camera,  tu fais comment? Tu créés une KeyMap? Mets ton code que je puisse voir parce que il y a quelque chose que je ne saisis pas.
Et au fait, tu compiles en statique ou tu utilises la dll. Si tu utilises la dll, faut voir si ton projet utilise bien la dernière dll que tu as compilé.

Dernière modification par johnplayer (06-07-2012 21:28:02)


core i7 4970K @ 4GHz - 32GB ddr3 19200(2400MHz) - ssd samsung 840 evo 250GB - GTX1080Ti (4K) - Cooler master storm stryker blanc.
"L'alcool, c'est comme Activia, c'est actif à l'intérieur et ça se voit à l'extérieur."

Hors ligne


#10 

07-07-2012 23:26:52

jeandu65200
Petit nouveau
Date d'inscription: 03-07-2012
Messages: 6

Salut wink n'arrivant pas à intégrer la modification du code source , j'ai décidé de le mettre directement dans mon code dans une classe hérité de ICameraSceneNode , que j'appelle dans l'event receiver lorsque la touche CTRL est appuyé .

Voila donc comment j'ai procédé :

Code c++ :

const irr::scene::ISceneNodeAnimatorList& animatorCamera = camera->getAnimators();
        it = animatorCamera.begin();
        while(it != animatorCamera.end())
        {

                collisionResponse =
                    static_cast<irr::scene::ISceneNodeAnimatorCollisionResponse *>(*it);

                                if(!collisionResponse->isFalling())
                    collisionResponse->setEllipsoidRadius(irr::core::vector3df(30, 20, 30));


            it++;
        }


Au fait les déclarations de it et de collisionResponse sont dans la déclaration de la classe . Lorsque j'appuie sur la touche CTRL , j'ai bien la caméra qui s'accroupit mais j'ai un autre problème : la caméra ne peut plus bouger , elle ne peut que sauter , je n'arrive pas à y remédier sad

Merci d'avance.

PS : Quand j'appelle setEllipsoidTranslation() , le programme cesse de fonctionner , bizarre oO

Dernière modification par jeandu65200 (07-07-2012 23:28:52)

Hors ligne


#11 

08-07-2012 14:44:47

johnplayer
Habitué
Date d'inscription: 30-09-2007
Messages: 431

Tu prends tout les animators comme des collision reponse, il faudrait peut-être prendre : ISceneNodeAnimator::getType() et le comparé à (irr::scene::ESCENE_NODE_ANIMATOR_TYPE) ESNAT_COLLISION_RESPONSE. Ainsi, tu ne modifies que l'animator concerné par la modif.

Pas besoin de créer une classe pour ce que tu veux faire.

Code:

/// création de la caméra
ISceneNodeAnimatorCameraFPS *camera = smgr->addCameraSceneNodeFPS(...);
/// création du selector
/*je te laisse le faire*/
/// création de la collision
irr::scene::ISceneNodeAnimator* anim = smgr->createCollisionResponseAnimator( selector, camera, irr::core::vector3df(50,20,50), irr::core::vector3df(0,0,0), irr::core::vector3df(0,30,0));
selector->drop();
camera->addAnimator(anim);
anim->drop();

/// dans OnEvent(const SEvent& event)
if (event.EventType == EET_KEY_INPUT_EVENT)
{
  if(event.KeyInput.PressedDown)
    if(event.KeyInput.Key == KEY_LCONTROL )
    {
      const irr::scene::ISceneNodeAnimatorList& animatorCamera = camera->getAnimators();
      it = animatorCamera.begin();
      while(it != animatorCamera.end())
      {
        if( it->getType() ==  ESNAT_COLLISION_RESPONSE) /// on ne s'intéresse qu'à l'AnimatorCollisionResponse
        {
          collisionResponse = static_cast<irr::scene::ISceneNodeAnimatorCollisionResponse *>(*it);
          if(!collisionResponse->isFalling())
            collisionResponse->setEllipsoidRadius(irr::core::vector3df(30, 20, 30)); /// se baisse
        }
        it++;
      }
      return true;
    }
    else
    {
      const irr::scene::ISceneNodeAnimatorList& animatorCamera = camera->getAnimators();
      it = animatorCamera.begin();
      while(it != animatorCamera.end())
      {
        if( it->getType() ==  ESNAT_COLLISION_RESPONSE) /// on ne s'intéresse qu'à l'AnimatorCollisionResponse
        {
          collisionResponse = static_cast<irr::scene::ISceneNodeAnimatorCollisionResponse *>(*it);
          if(!collisionResponse->isFalling())
            collisionResponse->setEllipsoidRadius(irr::core::vector3df(50, 20, 50));/// se relève
        }
        it++;
      }
      return true;
    }
}

Bon après comme tu le vois, il y a répétition du code donc une fonction te permettrait de ne pas avoir à appeler ta camera dans le OnEvent :

Code:

bool modifyEllipsoidRadius(irr::core::vector3df newradius)
{
      const irr::scene::ISceneNodeAnimatorList& animatorCamera = camera->getAnimators();
      it = animatorCamera.begin();
      while(it != animatorCamera.end())
      {
        if( it->getType() ==  irr::scene::ESNAT_COLLISION_RESPONSE)
        {
          collisionResponse = static_cast<irr::scene::ISceneNodeAnimatorCollisionResponse *>(*it);
          if(!collisionResponse->isFalling())
            collisionResponse->setEllipsoidRadius(newradius);
        }
        it++;
      }
   return true;
}

Il y a certainement des erreurs, je suis à moitié endormi ^^, je n'ai pas essayé le code parce que je l'ai tapé directement dans mon post. Donc je te laisses corriger.


core i7 4970K @ 4GHz - 32GB ddr3 19200(2400MHz) - ssd samsung 840 evo 250GB - GTX1080Ti (4K) - Cooler master storm stryker blanc.
"L'alcool, c'est comme Activia, c'est actif à l'intérieur et ça se voit à l'extérieur."

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
Analysé par
879 membres
1424 sujets
11113 messages
Dernier membre inscrit: brendan87
16 invités en ligne
Aucun membre connecté
RSS Feed