#1
Dans ce code, pour la simplicité, je n'est pas fait une classe "cameraFPS" mais intégrer son fonctionnement directement dans un code de base.
Aussi, j'ai laisser le curseur visible pour voir comment il réagit.
Voilà la bête:
J'ai commenté les lignes les plus importantes.
Et pour ceux que veulent la tester directement, l'exemple est téléchargeable ici:
une camera FPS
A+
14-04-2010 06:13:50
- nabouill
- Membres

- Date d'inscription:
- Messages: 242
- IP: 79.92.237.64
- Courriel
Voici une camera FPS que je trouve un peut optimisé. La différence avec celle intégré à Irrlicht:
- On peut lui indiquer des vitesses différente pour avancé, reculé et le déplacement latérale.
- elle se déplace parfaitement horizontalement, c'est à dire que contrairement a celle d'Irrlicht, elle ne saute pas sur place lorsque regarde vers le haut, ni se déplace 2 fois moins vite lorsqu'on regarde vers le bas (bien que l'on peut très facilement changer ce mode de déplacement et revenir au classique).
Dans ce code, pour la simplicité, je n'est pas fait une classe "cameraFPS" mais intégrer son fonctionnement directement dans un code de base.
Aussi, j'ai laisser le curseur visible pour voir comment il réagit.
Voilà la bête:
Code c++ :
#include <irrlicht.h>
using namespace std;
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace gui;
///////////////////////////////////////////////////////////////////////////////////////////////////////
/// GESTION EVENEMENT
///////////////////////////////////////////////////////////////////////////////////////////////////////
class MyEventReceiver : public IEventReceiver
{
public:
// This is the one method that we have to implement
virtual bool OnEvent(const SEvent& event)
{
// Remember whether each key is down or up
if (event.EventType == irr::EET_KEY_INPUT_EVENT)
KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
return false;
}
// This is used to check whether a key is being held down
virtual bool IsKeyDown(EKEY_CODE keyCode) const
{
return KeyIsDown[keyCode];
}
MyEventReceiver()
{
for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
KeyIsDown[i] = false;
}
private:
// We use this array to store the current state of each key
bool KeyIsDown[KEY_KEY_CODES_COUNT];
};
///////////////////////////////////////////////////////////////////////////////////////////////////////
/// MES FONCTIONS
///////////////////////////////////////////////////////////////////////////////////////////////////////
void moveCamera(irr::scene::ISceneNode *node, vector3df unite)
{
matrix4 m;
m.setRotationDegrees(vector3df(0, node->getRotation().Y, 0));
m.transformVect(unite);
node->setPosition(node->getPosition() + unite);
node->updateAbsolutePosition();
}
void targetCamera(ICameraSceneNode* camera)
{
vector3df rotCam = camera->getRotation();
vector3df pos(0.0f,0.0f,1000.0f);//1000 en Z pour regarder a 1000 unité devant nous
matrix4 mat;
mat.setRotationDegrees(rotCam);
mat.transformVect(pos);
camera->setTarget(camera->getAbsolutePosition() + pos);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
/// LA FONCTIONS MAIN
///////////////////////////////////////////////////////////////////////////////////////////////////////
int main()
{
int Lwindows = 640;//important de stocker la taille de la fenetre dans des variable pour positionner le curseur
int Hwindows = 480;
IrrlichtDevice *device = createDevice(EDT_DIRECT3D9, core::dimension2d<u32>(Lwindows,Hwindows),32,false,false,false);
IVideoDriver* driver = device->getVideoDriver ();
ISceneManager* sceneMgr = device->getSceneManager ();
MyEventReceiver myReceiver;
device->setEventReceiver(&myReceiver);
device->getCursorControl()->setVisible(true);
///creation d'une camera basic
ICameraSceneNode* myCamera = sceneMgr->addCameraSceneNode();
myCamera->setPosition(vector3df(1000,2000,1000));
//création du terrain
scene::ITerrainSceneNode* terrain = sceneMgr->addTerrainSceneNode(
"media/terrain-heightmap.bmp",
0,
-1,
core::vector3df(0.f, 0.f, 0.f),
core::vector3df(0.f, 0.f, 0.f),
core::vector3df(20.f, 1.0f, 20.f),
video::SColor ( 255, 255, 255, 255 ),
5,
scene::ETPS_17,
4
);
terrain->setMaterialFlag(video::EMF_LIGHTING, false);
terrain->setMaterialTexture(0,driver->getTexture("media/terrain-texture.jpg"));
terrain->setMaterialTexture(1,driver->getTexture("media/detailmap3.jpg"));
terrain->setMaterialType(video::EMT_DETAIL_MAP);
terrain->scaleTexture(1.0f, 20.0f);
// create triangle selector for the terrain
ITriangleSelector* selector = sceneMgr->createTerrainTriangleSelector(terrain, 0);
terrain->setTriangleSelector(selector);
// terrain->setVisible(false);
// create collision response animator and attach it to the camera
ISceneNodeAnimator* anim = sceneMgr->createCollisionResponseAnimator(
selector, myCamera,
vector3df(60,200,60),
vector3df(0,-10,0),
vector3df(10,10,10),
0.0001f);//pour un meilleur glissement
selector->drop();
myCamera->addAnimator(anim);
anim->drop();
///creation d'un curseur et initialisation des vitesse de deplacement de la camera
ICursorControl* curseur = device->getCursorControl();
//on met le curseur au milieu de l'ecran
curseur->setPosition(Lwindows/2,Hwindows/2);
f32 move_speed_front = 600;
f32 move_speed_back = 200;
f32 move_speed_latt = 300;
f32 rot_speed = 100;
u32 then = device->getTimer()->getTime();
u32 now = device->getTimer()->getTime();
f32 frameDeltaTime;
int fps;
int lastFPS;
while(device->run())
{
// Work out a frame delta time.
now = device->getTimer()->getTime();
frameDeltaTime = (f32)(now - then) / 1000.f; // Time in seconds
then = now;
///rotation
//on recupere la position du curseur
vector2d<f32> posMouse= curseur->getRelativePosition();
//on fait faire une rotation a la camera suivant la position du curseur
myCamera->setRotation(myCamera->getRotation()+
vector3df( (posMouse.Y - 0.5f)*rot_speed,
(posMouse.X - 0.5f) * rot_speed,
0));
//on verifie si notre camera ne regarde pas trop haut ou trop bas, sinon on ajuste
if(myCamera->getRotation().X > 89.0f)
{
myCamera->setRotation(vector3df(89, myCamera->getRotation().Y, 0.0f));
}
if(myCamera->getRotation().X < -89.0f)
{
myCamera->setRotation(vector3df(-89.0f, myCamera->getRotation().Y, 0.0f));
}
//mise a jour de la target
targetCamera(myCamera);
//on remet le curseur au milieu de l'ecran
curseur->setPosition(Lwindows/2,Hwindows/2);
/// pour avancé
if(myReceiver.IsKeyDown(KEY_UP))
{
f32 unit = move_speed_front*frameDeltaTime;
moveCamera(myCamera, vector3df(0,0.01,unit));
/* on a ajouté 0.01 sur l'axe Y, ceci ne parrait
abolument pas, mais empeche la camera a entrer
en collision avec des chose non souhaité */
}
/// pour RECULER
if(myReceiver.IsKeyDown(KEY_DOWN))
{
f32 unit = move_speed_back*frameDeltaTime;
moveCamera(myCamera, vector3df(0,0.01,-unit));
}
/// pour GAUCHE
if(myReceiver.IsKeyDown(KEY_LEFT))
{
f32 unit = move_speed_latt*frameDeltaTime;
moveCamera(myCamera, vector3df(-unit,0.01,0));
}
/// pour DROITE
if(myReceiver.IsKeyDown(KEY_RIGHT))
{
f32 unit = move_speed_latt*frameDeltaTime;
moveCamera(myCamera, vector3df(unit,0.01,0));
}
// pour quittez le programme
if(myReceiver.IsKeyDown(KEY_ESCAPE))
{ device->closeDevice();
}
driver->beginScene(true, true, SColor(0,0,255,255));
sceneMgr->drawAll();
driver->endScene();
fps = driver->getFPS();
if (lastFPS != fps)
{
core::stringw str = L"TEST CAMERA_FPS [";
str += driver->getName();
str += "] FPS:";
str += fps;
device->setWindowCaption(str.c_str());
lastFPS = fps;
}
}
device->drop();// destruction de device
return 0;
}
J'ai commenté les lignes les plus importantes.
Et pour ceux que veulent la tester directement, l'exemple est téléchargeable ici:
une camera FPS
A+
Hors ligne
#2
wofwar.olympe.in
30-05-2012 19:25:02
- Kirk
- Membres
- Date d'inscription:
- Messages: 14
- IP: 86.212.101.222
- Courriel
Merci c'est super mais on ne peut pas sauter...
wofwar.olympe.in
Hors ligne



