Historique des modifications - Message

Message #10006

Sujet: Soucis de deplacement


Type Date Auteur Contenu
Création du message 30-05-2011 14:17:41 Oelth
Bonjour,
après avoir tenté plusieurs recherches sur internet (sans grand succès malheureusement),
je souhaite solliciter humblement votre aide afin de palier à un soucis.
J'effectue actuellement un projet dans le cadre de mon DUT informatique,
et mon binôme et moi même avons choisi de développer un jeu sous Irrlicht.
Ça avance pas trop mal, mais un point que je n'ai pas résolu vient entacher tout ceci.
Lorsque je déplace mon personnage avec les touches Z,Q,S,D (au moyen de la classe eventReceiver),
ce dernier effectue une première transition/rotation, fige un court instant, joue l'animation (toujours sur place) puis
se décide enfin à avancer ou tourner.
Second soucis, lorsque je me déplace avec deux touches (exemple Z pour avancer et Q pour tourner à gauche), puis que j'en relâche une (dans le cas échéant Q) l'action de la touche qui reste pressée(donc Z) n'est plus effectuée.
J'ai beau avoir tourné ça dans tous les sens, je ne trouve pas de solution.
Si une âme charitable pouvait jeter un oeil à mon code, je lui en serais grandement reconnaissant !



Mon main
#include <irr/irrlicht.h>
#include "Multijoueurs.h"

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



int main()
{
	
	gui::IGUIEnvironment *gui;
	//Indique si le bouton jouer à été pressé
	bool jouer=false;
	//Indique si on joue en solo
	bool solo=false;
	//Indique si on joue en multijoueurs
	bool multijoueurs=false;
	//Indique si le bouton lancer serveur à été pressé
	bool lancerServeur=false;
	//Instance d'une partie en mode multijoueurs
	Multijoueurs * modeMulti;
	

	//Initialisation de la scene
		IrrlichtDevice *device = createDevice(
		video::EDT_OPENGL, // API OpenGL
		core::dimension2d<u32>(800,600), // Dimension Fenetre
		32, false, true, false, 0); // 2^32 valeur par pixel / plein écran / Stencil buffers / Synchronisation verticale / capteur d'évènement

	video::IVideoDriver *driver = device->getVideoDriver(); //Gère le rendu
	scene::ISceneManager *sceneManager = device->getSceneManager(); //Initialise la scène

	sceneManager->setAmbientLight(irr::video::SColorf(1.f,1.f,1.f,1.f)); //Definie la lumiere ambiante
	monEventReceiver * eventRec = new monEventReceiver(device);//Crée un capteur d'événements
    device->setEventReceiver(/*&*/eventRec);//Definie le capteur d'événements de la scene

	device->getCursorControl()->setVisible(false);//Masque le curseur
	device->setWindowCaption(L"Secret of template fantasy 2 : Back to the future of Template's life bis");//Definie le titre de la fenêtre


	/* MENU INITIALE */
	gui = sceneManager->getGUIEnvironment();
	video::ITexture *image = driver->getTexture("Textures/triforce.bmp");
	gui::IGUIButton *boutonJouer = gui->addButton(rect<irr::s32>(200,340,600,365),0,-1,L"Jouer");
	gui::IGUIButton *boutonMultijoueurs = gui->addButton(rect<irr::s32>(200,370,600,395),0,-1,L"Multijoueurs");
	gui::IGUIButton *boutonServeur = gui->addButton(rect<irr::s32>(200,400,600,425),0,-1,L"Lancer serveur");
	gui::IGUIButton *boutonQuitter = gui->addButton(rect<irr::s32>(200,430,600,455),0,-1,L"Quitter");


/**/while(device->run()) // Tant qu'on ne ferme pas l'appli           /**/
	{

		driver->beginScene(true,true,video::SColor(0,255,255,255)); // On definit la couleur du fond de scene
		if (jouer)//Si on a sélectionné l'option "jouer"
		{
			if(eventRec->IsKeyDown(irr::KEY_ESCAPE)){
				jouer = false;
				if(multijoueurs){
					multijoueurs = false;
					modeMulti->fermerConnexion();
				}else{
					solo = false;
				}
				
			}
			if(multijoueurs){
				modeMulti->routine();
				if(modeMulti->getCamera()) modeMulti->getCamera()->Update();//Mise à jour de la position de la camera
			}
			if(solo){
			}
			sceneManager->drawAll();//S'occupe du rendu géré par le scène manager
			
		}else{
						device->getCursorControl()->setVisible(true);//On affiche le curseur
						//On genere un menu
						driver->draw2DImage(image,position2d<irr::s32>(0,0),rect<irr::s32>(0,0,800,600), 0, video::SColor(255,255,255,255), true);
						gui->drawAll();//On rafraichit l'image
						if (boutonJouer->isPressed())//Si le bouton jouer est appuyé
						{
							jouer=true;//Jouer passe à vrai
						}
						if(boutonMultijoueurs->isPressed()){
							if(multijoueurs == false){
								modeMulti = new Multijoueurs(sceneManager,driver,device,eventRec);
								multijoueurs = true;
								jouer = true;
							}
						}
						if(boutonServeur->isPressed()){
							if(lancerServeur == false){
							system("start ../../serveur/Debug/serveur.exe");
							lancerServeur = true;
							}
						}
						if (boutonQuitter->isPressed())//Si le bouton quitter est appuyé
						{
							device->closeDevice();//On ferme la fenêtre
						}
		}
		driver->endScene(); //Affiche le rendu
	}
	device->drop(); //On libère la memoire
	return 0;
}

Ma classe Multijoueurs (où la scène se déroule)
#include "Multijoueurs.h"


Multijoueurs::Multijoueurs(scene::ISceneManager *pSceneManager,video::IVideoDriver *pDriver,IrrlichtDevice *pDevice, monEventReceiver * pEventRec)
{
	mSceneManager = pSceneManager;
	//Port
	this->portServeur = 10000;
	//Notre ID
    this->my_ID_Joueur = -1;
    //ID des autres joueurs
    this->un_ID_Joueur = 0;
	//Indique si notre personnage marche
	this->je_marche = false;
	//Indique si un autre personnage marche
    this->il_marche = false;
	//Ces deux variables permettront de calculer le laps de temps ecoulé entre deux envois de messages
    this->tempsActuel = clock();
    this->tempsEcouler = clock();
	//Création de l'interface serveur
	this->client = RakNet::RakPeerInterface::GetInstance();
    //Creation d'un packet
    this->packet = NULL;
	this->mDriver = pDriver;
	this->mDevice = pDevice;
	eventRec = pEventRec;

	

	//Saisie de l'adresse du serveur
    printf("Entrez l'adresse IP du serveur :");
    scanf("%s", this->IP_serveur);

	connexionAuServeur();
	initialisationNiveau();
	initialisationPersonnages();
	initialisationEclairage();
	initialisationCiel();
	attenteConnexion();
}
/*************************************************************************************/
Multijoueurs::~Multijoueurs(void)
{
	RakNet::RakPeerInterface::DestroyInstance(client);//On detruit le client
}
/*************************************************************************************/
void Multijoueurs::connexionAuServeur(){
	//Demarrage du client
    this->client->Startup(1,&RakNet::SocketDescriptor(), 1);
    this->client->Connect(IP_serveur, portServeur, 0,0);
}
/*************************************************************************************/
void Multijoueurs::initialisationNiveau(){

	map = new Carte(mSceneManager,mDriver,"Textures/terrain_heightmap.bmp","Textures/grass.jpg","terrain",core::vector3df(40.f, 4.4f, 40.f));

}
/*************************************************************************************/
void Multijoueurs::initialisationPersonnages(){

	for(int i = 0; i < JOUEURS_MAX;i++){
	sydney[i] = new Personnages("Textures/sydney.md2","Textures/sydney.bmp",mSceneManager,mDevice,5900,100,6975);
	selector = mSceneManager->createOctreeTriangleSelector(sydney[i]->getPersonnage()->getMesh(),map->getCarte(), 128);//Definition des contraintes
																					//du selector (mesh de l'élément) qui entrera en collision																		//definition du node avec lequel le mesh entrera en collision

	map->getCarte()->setTriangleSelector(selector);
	sydney[i]->getPersonnage()->setVisible(false);
	selector->drop();
	}

	
}
/*************************************************************************************/
void Multijoueurs::attenteConnexion(){
	
// On fait une boucle pour la connexion, ici on va attendre de savoir si la connection
// au serveur est OK ou non et attendre de recevoir un ID envoyer par le serveur
// on continue cette boucle temps que notre ID est inferieur à 0.
do
{
		packet = client->Receive();
		if(packet != NULL)// si oui
		{
			unsigned char packetID;
			//creation de data que l'on est pret a recevoir
			RakNet::BitStream dataStream(packet->data, packet->length, false);
			// on commence par lire l'ID du paquet que l'on vient de recevoir
			dataStream.Read(packetID);
			switch(packetID)
			{
				case ID_CONNECTION_REQUEST_ACCEPTED:
						 printf("La connexion au serveur a bien ete acceptee\
");
						 break;

				case ID_CONNECTION_ATTEMPT_FAILED:
								//on reçois cet ID automatiquement si on arrive pas a ce connecter au serveur
								printf("La connexion au serveur a echoue !!!\
");
								break;

				//le packet qui nous donne notre ID joueur
				case PACKET_ID_ID_JOUEUR:
						dataStream.Read(my_ID_Joueur);
						printf("Reception de l'ID: %d\
", my_ID_Joueur);
						sydney[my_ID_Joueur]->getPersonnage()->setVisible(true);
						sydney[my_ID_Joueur]->getPersonnage()->setName("joueur");
						sydney[my_ID_Joueur]->getPersonnage()->setPosition(vector3df(5900,100,6975));
						mCamera = new FollowingCamera(sydney[my_ID_Joueur]->getPersonnage(), mSceneManager,//Creation de la camera
													  false,           // Pour utiliser une position initiale.
													  selector,       // Pour les collisions.
													  100,            // Distance.
													  50,             // Hauteur.
													  30,             // Delta cible.
													  vector3df(-50,200,-120));   // Position initiale.      
						mSceneManager->setActiveCamera( mCamera->getCam() );  
						break;


			}
		}
	}while(my_ID_Joueur < 0);//c'est que l'on a bien reçu notre ID
}
/*************************************************************************************/
void Multijoueurs::routine(){
	/*RESEAU*/

		//on verifie si on a reçu un packet
        packet = client->Receive();
        if(packet != NULL)// si oui
        {
               unsigned char packetID;
                //creation de data que l'on est pret a recevoir
                RakNet::BitStream dataStream(packet->data, packet->length, false);
                // on commence par lire l'ID du paquet que l'on vient de recevoir
                dataStream.Read(packetID);

                switch(packetID)
                {
                    //un packet qui indique la position des joueurs
                    case PACKET_ID_DEPLACEMENT:
                            dataStream.Read(un_ID_Joueur);//on lit l'ID du joueur a qui correspond cette position
                            dataStream.Read(une_position);//on lit la position
                            dataStream.Read(une_rotation);//puis la rotation
                            //bien sur on n'effectue un changement sur la position du joueur
                            //seulement si c'est pas le notre
                            if(un_ID_Joueur != my_ID_Joueur)
                            {   //on place le joueur et on le tourne par rapport au valeur reçu precedement
								sydney[un_ID_Joueur]->getPersonnage()->setPosition(une_position);
                                sydney[un_ID_Joueur]->getPersonnage()->setRotation(une_rotation);
                            }
                            break;

                    //un packet qui indique l'animation des autres joueurs
                    case PACKET_ID_ANIMATION:
                            dataStream.Read(un_ID_Joueur);//on lit l'ID du joueur a qui correspond cette position
							if(un_ID_Joueur != my_ID_Joueur){
                            dataStream.Read(il_marche);//on lit si il marche
                            if(il_marche)
                            {
								sydney[un_ID_Joueur]->getPersonnage()->setMD2Animation(EMAT_RUN);
								if(!sydney[un_ID_Joueur]->getPersonnage()->isVisible()){
									sydney[un_ID_Joueur]->getPersonnage()->setVisible(true);
								}
                            }
                            else
                            {
								sydney[un_ID_Joueur]->getPersonnage()->setMD2Animation(EMAT_STAND);
							}}
                            break;


                    default:
                        // si on l'ID d'un paquet que l'on a pas referencer on le dit
                        //ceci n'est pas forcement un probleme !
                        printf("Reception d'un packet avec un ID inconnu: %i\
", int(packetID));
                }

            client->DeallocatePacket(packet);//on vide le packet
        }



			//Si on presse la touche Z ou la touche S
			if(eventRec->IsKeyDown(irr::KEY_KEY_Z) || eventRec->IsKeyDown(irr::KEY_KEY_S))
                {
					//Si l'animation de marche n'etait pas activée
                    if(!je_marche)
                    {   //On indique que l'animation est lancée
                        je_marche = true;
                        //On envoie un message au serveur pour indiquer qu'on joue l'animation
                        RakNet::BitStream data;
                        data.Write(PACKET_ID_ANIMATION);//On indique que c'est une animation
                        data.Write(my_ID_Joueur);//On ecrit notre ID afin que le serveur sache de qui il s'agit
                        data.Write(je_marche);//On indique l'etat de l'animation de marche
                        //On envoie le message au serveur
                        client->Send(&data, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true);
						//On detruit l'instance data
						data.DestroyInstance;
                    }
                }
        else//Si l'on appuie ni sur Z ni sur S
            {
                //Si l'animation marche est activée
                if(je_marche)
                {
					//On indique que l'animation à cessé
                    je_marche = false;
					//On envoie un message au serveur pour indiquer qu'on ne joue plus l'animation
                    RakNet::BitStream data;
                    data.Write(PACKET_ID_ANIMATION);//On indique que c'est une animation
                    data.Write(my_ID_Joueur);//On ecrit notre ID afin que le serveur sache de qui il s'agit
                    data.Write(je_marche);//On indique l'etat de l'animation de marche
                    //On envoie le message au serveur
                    client->Send(&data, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true);
					//On detruit l'instance data
					data.DestroyInstance;
				}
            }
			


		 tempsEcouler = clock();//Mise a jour du temps ecoulé
    if(tempsEcouler - tempsActuel > 30)//Si plus de 30 ms se sont ecoulées
    {
            RakNet::BitStream data;
            data.Write(PACKET_ID_DEPLACEMENT);//On indique que c'est une animation
            data.Write(my_ID_Joueur);//On ecrit notre ID afin que le serveur sache de qui il s'agit
			une_position = sydney[my_ID_Joueur]->getPersonnage()->getAbsolutePosition();//On recupere notre position
            data.Write(une_position);//On l'ecrit dans le packet
			une_rotation = sydney[my_ID_Joueur]->getPersonnage()->getRotation();//On recupere notre rotation
            //On remet la rotation des axes X et Z a zéro afin de ne pas avoir un personnage dans des positions incoherentes
            une_rotation.X = 0;
            une_rotation.Z = 0;
            data.Write(une_rotation);//On ecrit la rotation dans le packet
            //On envoie le message au serveur
            client->Send(&data, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true);

        tempsActuel = clock();//On met le temps a jour
    }
}
/*************************************************************************************/
void Multijoueurs::initialisationCiel(){
		mSky = mSceneManager->addSkyBoxSceneNode(mDriver->getTexture("Textures/irrlicht2_up.jpg"),
                                                               mDriver->getTexture("Textures/irrlicht2_dn.jpg"),
                                                               mDriver->getTexture("Textures/irrlicht2_lf.jpg"),
                                                               mDriver->getTexture("Textures/irrlicht2_rt.jpg"),
                                                               mDriver->getTexture("Textures/irrlicht2_ft.jpg"),
                                                               mDriver->getTexture("Textures/irrlicht2_bk.jpg"));
}
/*************************************************************************************/
void Multijoueurs::initialisationEclairage(){
	mSceneManager->setAmbientLight(irr::video::SColorf(0.5f,0.5f,0.5f,1.0f));
	// On crée une lumière diffuse
    scene::ILightSceneNode* sun = mSceneManager->addLightSceneNode();
    // On specifie la distance que peut atteindre cette lumière
    sun->setRadius(100000);
    // On specifie la position de la lumière dans la scene
    sun->setPosition(core::vector3df(8000, 2000, 8000));
}
/*************************************************************************************/
FollowingCamera* Multijoueurs::getCamera(){
	return mCamera;
}
/*************************************************************************************/
void Multijoueurs::fermerConnexion(){
	client->CloseConnection(client->GetSystemAddressFromIndex(0),true,0,HIGH_PRIORITY);
}

Ma classe eventReceiver
#include "monEventReceiver.h"
float PI=3.14;

    monEventReceiver::monEventReceiver(IrrlichtDevice* device)
    {
        mDevice = device;
		for(int i=0; i<irr::KEY_KEY_CODES_COUNT; i++)
            //mKeyState[i] = false;
			keyMap[i] = false;
		courseActive = false;
    }
 
	bool monEventReceiver::OnEvent(const SEvent& event)
    {

		if (event.EventType == irr::EET_KEY_INPUT_EVENT) {
			keyMap[event.KeyInput.Key] = event.KeyInput.PressedDown;
			OnPreRender();
		return event.KeyInput.PressedDown;
		}else{
			return false;
		}
}


void monEventReceiver::OnPreRender(){

		bool retourActionOriginale = true;
		core::vector3df positionPersonnage;
		core::vector3df rotationPersonnage;
        scene::ISceneManager* smgr = mDevice->getSceneManager();
		scene::IAnimatedMeshSceneNode* joueur = (scene::IAnimatedMeshSceneNode*)smgr->getSceneNodeFromName("joueur");
		scene::ITerrainSceneNode* terrain = (scene::ITerrainSceneNode*)smgr->getSceneNodeFromName("terrain");

		
		if(keyMap[KEY_ESCAPE]){
			//mDevice->closeDevice();
		}


		if (keyMap[irr::KEY_KEY_Z]){//Avancer
		
						facing.set( -cos( joueur->getRotation().Y * PI/180.0f ), 0, sin( joueur->getRotation().Y * PI/180.0f ) ); 
						facing.normalize(); 
						positionPersonnage = joueur->getPosition() - (facing*5.0f)  ; 
						positionPersonnage.Y = terrain->getHeight(positionPersonnage.X,positionPersonnage.Z) + 24;
						joueur->setPosition( positionPersonnage ); 
						
       

							if(!this->courseActive){
							joueur->setMD2Animation(scene::EMAT_RUN);
							this->courseActive = true;
							}
	}


			if (keyMap[irr::KEY_KEY_S]){//Reculer

						facing.set( cos( joueur->getRotation().Y * PI/180.0f ), 0, -sin( joueur->getRotation().Y * PI/180.0f ) ); 
						facing.normalize(); 
						positionPersonnage = joueur->getPosition() - (facing*5.0f)  ; 
						positionPersonnage.Y = terrain->getHeight(positionPersonnage.X,positionPersonnage.Z) + 24;
						joueur->setPosition( positionPersonnage ); 

							if(!this->courseActive){
								joueur->setMD2Animation(scene::EMAT_RUN);
							this->courseActive = true;
							}

	}



	if (keyMap[irr::KEY_KEY_Q]){//Rotation à gauche
						joueur->setRotation(joueur->getRotation() + core::vector3df(0.0f,-5.0f,0.0f));
						if(rotationPersonnage.Y >= 360){
							rotationPersonnage.Y -= 360;
							joueur->setRotation(rotationPersonnage);
						}
	}

	
	if (keyMap[irr::KEY_KEY_D]){//Rotation à droite
		
						joueur->setRotation(joueur->getRotation() + core::vector3df(0.0f,5.0f,0.0f));
						if(rotationPersonnage.Y >= 360){
							rotationPersonnage.Y -= 360;
							joueur->setRotation(rotationPersonnage);

			}
		}


	if((!keyMap[irr::KEY_KEY_S])&&(!keyMap[irr::KEY_KEY_Z])){
		if(courseActive == true){
		joueur->setMD2Animation(scene::EMAT_STAND);
		this->courseActive = false;}
	}

	

}

bool monEventReceiver::IsKeyDown(EKEY_CODE keyCode) const
{
	return keyMap[keyCode];
}

Merci beaucoup par avance smile.

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
148 invités en ligne
membre en ligne: -
RSS Feed