Historique des modifications - Message

Message #8312

Sujet: Mouvement fluide ?


Type Date Auteur Contenu
Dernière modification 24-06-2010 09:25:54 adiems
Salut, t'as sans doute déjà trouvé une solution à ton problème mais bon,

Le problème dans ton code, c'est surtout que ton while gérant ton déplacement est dans ta boucle de jeu...donc à chaque rendu, tu effectue le déplacement complet et non pas les 10 étapes sur 10 rendus (qui donnerait une animation de ton déplacement).
Bon après même en corrigeant ça, ça n'est pas une bonne idée de faire le déplacement en fonction de la vitesse d'exécution de ton ordi, dans le cas présent: metytons que tu tournes à 1fps, ton déplacement prendrait 10 secondes, mais si tu tournes à 10fps, le déplacement prendra 1 seconde, alors imagine avec un fps élevé...

C'est pour ça que d'ans l'exemple il utilise le temps passé comme coefficient.


pourquoi tu ne fais pas une interpolation linéaire de la position par rapport au temps: ton déplacement sera fluide (si t'as un fps correct (>25 sinon ça lag et on n'y peut rien), et indépendant du fps (sur un autre ordinateur plus lent ou plus rapide, ton déplacement prendra le même temps et se fera à la même vitesse)
C'est pas bien compliqué à mettre en pratique, il te faut :
  • La position de départ (pointDepart)
  • La position d'arrivée souhaitée (pointArrivee)
  • Le temps au moment du départ (tempsDepart)
  • Le temps de déplacement souhaité (tempsParcours)(il peut être fixe et donc ton déplacement sera plus ou moins rapide en fonction de la distance à parcourir, ou bien tu le calcule en fonction de la vitesse qui sera fixe et de la distance à parcourir )


donc au moment où tu lance le déplacement, tu récupères le temps courant dans tempsDepart, la position actuelle dans pointDepart, la position voulue dans pointArrivee et tu décides d'un temps de parcours.
Ensuite à chaque tour de boucle de jeu, tu mets à jour la position en faisant le ratio du temps passé par rapport au temps de parcours total et tu applique ce même ratio sur la position suivant la ligne entre le point de départ et le point d'arrivée ( déplacement = tempsPasséDepuisLeLancement * DistanceAParcourir / TempsTotalParcours) :

...
// Au lancement de ton déplacement
pointDepart = position;
pointArrivee = target; // à toi de décider où aller
tempsDepart = device->getTimer()->getTime();
bouge = true;

...
// puis tant que le déplacement est actif, à chaque tour de boucle de jeu (typiquement dans l'appel que fait Irrlicht sur tes nodes avant chaque rendu : onAnimate() )
if( bouge )
{
    irr::u32 now = device->getTimer()->getTime();

    // mise à jour de la position  (c'est ine version simplifiée pour le principe, il faudrait faire attention aux coordonnées négatives dans la soustraction...)
    position.X = pointDepart.X + ( (now-tempsDepart)  * (pointArrive..X - pointDepart.X) ) / tempsParcours );
    position.X = pointDepart.Y + ( (now-tempsDepart)  * (pointArrive..Y - pointDepart.Y) ) / tempsParcours );
    position.X = pointDepart.Z + ( (now-tempsDepart)  * (pointArrive..Z - pointDepart.Z) ) / tempsParcours );
    if( ( now - tempsDepart ) >= tempsParcours )
    {
          bouge = false; // tu es arrivé
          poistion = pointArrivee; // on recale au cas où on serait pas tombé pile poil sur la bonne position d'arrivée
    }
}

Après, à toi d'encapsuler ça dans des fonctions et dans des classes...
Création du message 24-06-2010 09:23:41 adiems
Salut, t'as sans doute déjà trouvé une solution à ton problème mais bon,

Le problème dans ton code, c'est surtout que ton while gérant ton déplacement est dans ta boucle de jeu...donc à chaque rendu, tu effectue le déplacement complet et non pas les 10 étapes sur 10 rendus (qui donnerait une animation de ton déplacement).
Bon après même en corrigeant ça, ça n'est pas une bonne idée de faire le déplacement en fonction de la vitesse d'exécution de ton ordi, dans le cas présent: metytons que tu tournes à 1fps, ton déplacement prendrait 10 secondes, mais si tu tournes à 10fps, le déplacement prendra 1 seconde, alors imagine avec un fps élevé...

C'est pour ça que d'ans l'exemple il utilise le temps passé comme coefficient.


pourquoi tu ne fais pas une interpolation linéaire de la position par rapport au temps: ton déplacement sera fluide (si t'as un fps correct (>25 sinon ça lag et on n'y peut rien), et indépendant du fps (sur un autre ordinateur plus lent ou plus rapide, ton déplacement prendra le même temps et se fera à la même vitesse)
C'est pas bien compliqué à mettre en pratique, il te faut :
  • La position de départ (pointDepart)
  • La position d'arrivée souhaitée (pointArrivee)
  • Le temps au moment du départ (tempsDepart)
  • Le temps de déplacement souhaité (tempsParcours)(il peut être fixe et donc ton déplacement sera plus ou moins rapide en fonction de la distance à parcourir, ou bien tu le calcule en fonction de la vitesse qui sera fixe et de la distance à parcourir )


donc au moment où tu lance le déplacement, tu récupères le temps courant dans tempsDepart, la position actuelle dans pointDepart, la position voulue dans pointArrivee et tu décides d'un temps de parcours.
Ensuite à chaque tour de boucle de jeu, tu mets à jour la position en faisant le ratio du temps passé par rapport au temps de parcours total et tu applique ce même ratio sur la position suivant la ligne entre le point de départ et le point d'arrivée ( déplacement = tempsPasséDepuisLeLancement * DistanceAParcourir / TempsTotalParcours) :

...
// Au lancement de ton déplacement
pointDepart = position;
pointArrivee = target; // à toi de décider où aller
tempsDepart = device->getTimer()->getTime();
bouge = true;

...
// puis tant que le déplacement est actif, à chaque tour de boucle de jeu (typiquement dans l'appel que fait Irrlicht sur tes nodes avant chaque rendu : onAnimate() )
if( bouge )
{
    irr::u32 now = device->getTimer()->getTime();

    // mise à jour de la position  (c'est ine version simplifiée pour le principe, il faudrait faire attention aux coordonnées négatives dans la soustraction...)
    position.X = pointDepart.X + ( (now-tempsDepart)  * (pointArrive..X - pointDepart.X) ) / tempsParcours );
    position.X = pointDepart.Y + ( (now-tempsDepart)  * (pointArrive..Y - pointDepart.Y) ) / tempsParcours );
    position.X = pointDepart.Z + ( (now-tempsDepart)  * (pointArrive..Z - pointDepart.Z) ) / tempsParcours );
    if( ( now - tempsDepart ) >= tempsParcours )
    {
          bouge = false; // tu es arrivé
          poistion = pointArrivee; // on recale au cas où on serait pas tombé pile poil sur la bonne position d'arrivée
    }
}

Après, à toi d'encapsuler ça dans des fonctions et dans des classes...

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