#0 

13-03-2014 16:01:52

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

Bonjour tout les monde,

Pour ceux que çà intéresse, j'ai pris un peut de mon temps pour faire une camera à la troisième personne, la plus simple possible et en m'inspirant d'autres codes trouvé sur le net.

Tout d'abord une petite classe camera pour accueillir notre unique fonction :S (camera.h)

Code c++ :

#ifndef CAMERA_H
#define CAMERA_H

#include <stdlib.h>
#include <stdio.h>
#include <cstdio>
#include <string>
#include <iostream>
#include <direct.h>
#include <windows.h>
#include <time.h>

#include <irr/irrlicht.h>

/** Déclarations anticipées **/
using namespace std;
using namespace irrklang;
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;


class Camera
{
    public:

        //! constructeur
        Camera();
        //! destructeur
        ~Camera();

        void moveCameraControl(ICameraSceneNode *camera,
                               ISceneManager *smgr,
                               IAnimatedMeshSceneNode* Node,
                               float Horizontal,float Vertical,float VitesseCamera);

    private:

        float direction;
        float zdirection;

    protected:

};

#endif // CAMERA_H


En suite le fichier camera.cpp qui va avec :

Code c++ :

#include <stdlib.h>
#include <stdio.h>
#include <cstdio>
#include <string>
#include <iostream>
#include <direct.h>
#include <windows.h>
#include <time.h>
#include <cstring>
#include <sstream>

#include <irr/irrlicht.h>
#include <irrklang/irrKlang.h>
#include "Camera.h"

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

enum    ///***Enumeration des ID
{
};

//! constructeur
Camera::Camera():direction(0), zdirection(0)
{
//ctor
}

//! destructeur
Camera::~Camera()
{
}

void Camera::moveCameraControl(ICameraSceneNode *camera,           //-----> camera crée dans le scene
                                                   ISceneManager *smgr,                      //-----> sceneManager
                                                   IAnimatedMeshSceneNode* Node,      //-----> Node du personnage
                                                   float Horizontal,float Vertical,float VitesseCamera) //--------> Pour choisir mouvement horizontal en envoi 1.0, 0.0, 0.5 -> le dernier est la vitesse
{

     core::vector3df cameraPos = camera->getAbsolutePosition();

     direction = direction + VitesseCamera *(Horizontal);
     zdirection = zdirection - VitesseCamera * (Vertical);

     if( zdirection <- 90 )
         zdirection = -90;
     else
     if( zdirection > 90 )
         zdirection = 90;

     core::vector3df playerPos = Node->getPosition();

     float xf = playerPos.X - cos( direction * PI / 180.0f ) * 64.0f;
     float yf = playerPos.Y - sin( zdirection * PI / 180.0f ) * 64.0f;
     float zf = playerPos.Z + sin( direction * PI / 180.0f ) * 64.0f;

     camera->setPosition( core::vector3df( xf, yf, zf ) );
     camera->setTarget( core::vector3df( playerPos.X, playerPos.Y+25.0f, playerPos.Z ) );
     //Node->setRotation( core::vector3df( 0, direction, 0 ) ); // -> Pour que le personnage suive la direction de la camera
}


Maintenant il faut juste mettre a jour la camera dans la partie jeux :
Moi j'ai fais comme çà mais après il y a surement d'autres solutions ...

Code c++ :

#ifndef APPLICATION_H
#define APPLICATION_H
#include "irr/IEventReceiver.h"
#include "irr/irrArray.h"
#include <stdlib.h>
#include <stdio.h>
#include <cstdio>
#include <string>
#include <iostream>
#include <direct.h>
#include <windows.h>
#include <time.h>

#include <irr/irrlicht.h>


#include "Camera.h" // -------------------------------> A ne pas oublier

/** Déclarations anticipées **/
using namespace std;
using namespace irrklang;
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;


class Application : public irr::IEventReceiver // On dérive la classe Application pour gérer les événements
{
    public:

        //! constructeur
        Application();
        //! destructeur
        virtual ~Application();

        //! créé l'environnement Irrlicht
        bool run();

        //! Boucle de rendu
        void rendu();

        //! gestion des événements
        bool OnEvent(const irr::SEvent& event);


        //! Mouvement de la camera
        void UpdateCameraMovement();  //-------------------------> Pour mettre a jour la position de la camera


    protected:
        //! MEMBRES
        irr::IrrlichtDevice *device;
        irr::video::IVideoDriver *driver;
        irr::scene::ISceneManager *smgr;
        irr::gui::IGUIEnvironment *env;


        //cameras
        ICameraSceneNode *camera[2]={0,0};  //----> Deux camera mais une seule suffit wink

        IAnimatedMeshSceneNode *model_node; //----> le personnage

        bool cameraH_Positif;    //-------------------> Pour les Evénements on va pouvoir déterminer quel mouvement de camera réaliser
        bool cameraH_Negatif;
        bool cameraV_Positif;
        bool cameraV_Negatif;

        Camera came;   // ---------------------------> On cree un objet camera

    private:

};

#endif // APPLICATION_H


Et pour finir la partie du jeux .cpp

Code c++ :

void Application::UpdateCameraMovement(){
     if(cameraV_Positif == true){
        came.moveCameraControl(camera[0],smgr,model_node,0,1,0.5);
     }
     if(cameraV_Negatif == true){
        came.moveCameraControl(camera[0],smgr,model_node,0,-1,0.5);
     }
     if(cameraH_Positif == true){
        came.moveCameraControl(camera[0],smgr,model_node,1,0,0.5);
     }
     if(cameraH_Negatif == true){
        came.moveCameraControl(camera[0],smgr,model_node,-1,0,0.5);
     }
     if(cameraV_Positif == false || cameraV_Negatif == false || cameraH_Positif == false || cameraH_Negatif == false){
        came.moveCameraControl(camera[0],smgr,model_node,0,0,0);

     }

}



bool  Application::OnEvent(const SEvent& event){
switch(event.EventType)
    {
        case EET_KEY_INPUT_EVENT:
        {
            // si on appuie sur echap
            if(event.KeyInput.Key == KEY_ESCAPE && event.KeyInput.PressedDown)
            {
                // on ferme l'application
                printf("FERMETURE");
                device->closeDevice();
                return true;
            }

            if(event.KeyInput.Key == irr::KEY_KEY_Z)
                {
                    if(event.KeyInput.PressedDown == true)          //Si il s'agit d'un appui
                        cameraV_Positif = true; //-------------------------------------------------> Mouvement vertical positif
                    //Sinon c'est un relachement
                       else cameraV_Positif = false;
                    return true;
                }
            if(event.KeyInput.Key == irr::KEY_KEY_S)
                {
                    if(event.KeyInput.PressedDown == true)
                        cameraV_Negatif = true; //-------------------------------------------------> Mouvement vertical negatif
                    else cameraV_Negatif = false;
                    return true;
                }
             if(event.KeyInput.Key == irr::KEY_KEY_Q)
                {
                    if(event.KeyInput.PressedDown == true)          //Si il s'agit d'un appui
                        cameraH_Positif = true; //-------------------------------------------------> Mouvement horizontal positif
                    //Sinon c'est un relachement
                    else cameraH_Positif = false;
                    return true;
                }
            if(event.KeyInput.Key == irr::KEY_KEY_D)
                {
                    if(event.KeyInput.PressedDown == true)
                        cameraH_Negatif = true; //-------------------------------------------------> Mouvement horizontal negatif
                    else cameraH_Negatif = false;
                    return true;
                }
        }
        break;
        default: break;
    }
}


Puis dans la boucle de rendu :

Code:

UpdateCameraMovement();

Voila même si c'est pas grand chose, j’espère que çà sera utile...

Bonne continuation.

Hors ligne


#1 

14-03-2014 19:08:46

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 904
Corrections: 2
Site web

merci pour le partage wink

juste quelsque remarque:

organise t'est include pour que ce soit portable du premier coup
a savoir

Code c++ :


#include <stdlib.h>
#include <stdio.h>
#include <cstdio>
#include <string>
#include <iostream>
#include <direct.h>
#include <windows.h>
#include <time.h>
#include <cstring>
#include <sstream>
#include <irrklang/irrKlang.h>



non indispensable au comportement, pas nécessaire a reinclure dans les *.cpp s'il sont inclue dans le header

et éviter les using namespace dans les headers:

Code c++ :


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


pensse a mettre t'est fonctions en virtual ça peut aider plus tard (pour ta class Camera)

sinon c'est plutot propre

si tu veut aller un peut plus loin tu peut regarder du coter de  ISceneNodeAnimator wink

Hors ligne


#2 

15-03-2014 08:31:24

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

Merci pour tes remarques je vais les prendres en compte pour améliorer mon code.

On ne peut vraiment pas utiliser les namespaces dans les header? En quoi cela est il néfaste? Il y a une autre façon de les annoncer peut être?

Qu'entend tu par fonction virtual? J'avais déjà cherché ce que c'était mais en ais pas vraiment comprit l'intérêt.

Et oui on Ma déjà proposé de regarder du côté des animators mais je suis limité à ce que je sais faire. Tu penses quil y a mieux à faire? Ma caméra est plutôt gourmande en terme de ressources non ?

Hors ligne


#3 

16-03-2014 12:58:42

Magun
SleekThink Producer
Lieu: Punakha
Date d'inscription: 18-11-2007
Messages: 904
Corrections: 2
Site web

le soucis de l'utilisation des namespaces dans les header c'est surtout que rien ne garantie qu'un namespace du même nom n'existe pas ailleur dans le projet host
par exemple core, video, scene, ... sont des nom asser usuel or si tu utilise <<using namespace irr>> il y a de forte probabiliter qu'il y est des conflits

les fonctions virtuel permette de pouvoir utiliser le polymorphisme
si tu dérive une class et que tu redefini une fonctions virtuel, peut import la déclaration que tu utilise (fils ou mère)
la fonction utiliser seras celle de l'instance de la class
si tu ne le fait pas c'est celle de la déclaration qui seras usé

(peut-être que je ne suis pas asser claire)
ça permet d'étendre ton code sans toucher au base

pour finir, l'interet de passer par un animator c'est de décharger le programmeur sur la mise a jours de la position de la camera et evenement
et de plus de pouvoir l'exporter simplement dans les scenes *.irr avec une class a deriver pour l'importation (irr::scene::ISceneUserDataSerializer)

il suffie alors de faire un code de ce style:

Code c++ :


ICameraSceneNode *cam = smgr->addCameraSceneNode();
ISceneNodeAnimator *rpg = new Camera();
cam->addAnimator(rpg);
rpg->drop();


rien de plus

wink

une dernier chose

Code c++ :


            if(event.KeyInput.Key == irr::KEY_KEY_S)
                {
                    if(event.KeyInput.PressedDown == true)
                        cameraV_Negatif = true; //-------------------------------------------------> Mouvement vertical negatif
                    else cameraV_Negatif = false;
                }

equivalent a

Code c++ :


cameraV_Positif = event.KeyInput.Key == irr::KEY_KEY_S && event.KeyInput.PressedDown;

Hors ligne


#4 

16-03-2014 15:26:33

jonath313
Abonné
Date d'inscription: 28-12-2009
Messages: 240

Enfait par rapport à mon code il suffit que je declare ma class :

Code c++ :

class Camera : ISceneNodeAnimator
{
    public:
    ...
}


Je suis un peut perdu car vue que ma class camera avait une seule fonction je n'envoyai plus l'interet alors j'ai mis la fonction de la camera dans la classe de creation d'un joueur :

Code c++ :

void Player::moveCameraControl(ICameraSceneNode *camera,
                                ISceneManager *smgr,
                                float Horizontal,
                                float Vertical,
                                float VitesseCamera,
                                f32 TimeElap)
{
     direction = direction + VitesseCamera * (Horizontal) * TimeElap * 250.0f;
     zdirection = zdirection - VitesseCamera * (Vertical) * TimeElap * 250.0f;

     if( zdirection <- 90 )
         zdirection = -90;
     else
     if( zdirection > 90 )
         zdirection = 90;


     core::vector3df playerPos = NodePlayer->getPosition();

     float xf = playerPos.X - cos( direction * PI / 180.0f ) * 64.0f;
     float yf = playerPos.Y - sin( zdirection * PI / 180.0f ) * 64.0f;
     float zf = playerPos.Z + sin( direction * PI / 180.0f ) * 64.0f;

     camera->setPosition( core::vector3df( xf, yf, zf ) );
     camera->setTarget( core::vector3df( playerPos.X, playerPos.Y+25.0f, playerPos.Z ) );

     //NodePlayer->setRotation( core::vector3df( 0, direction, 0 ) );
}


Comme çà je récupère directement la position du joueur.

Dans la boucle,la fonction est appelée si on a appui sur une touche.

Admettons que l'on ajoute le système d'animateur, çà reviendrait concrètement à recréer une class pour ma caméra, la mettre en ISceneNodeAnimator , et créer des  animateurs pour chacune des caméras.

Je me suis perdus dans ma question...

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
880 membres
1424 sujets
11113 messages
Dernier membre inscrit: mandrifidy
30 invités en ligne
Aucun membre connecté
RSS Feed