Comment obtenir et utiliser le temps delta

14

J'ai des souris qui cherchent et marchent dans mon jeu, mais elles sont très lentes et difficiles à utiliser. Je pense que c'est parce que j'utilise une vitesse fixe. J'ai entendu dire que dans les grands projets, les développeurs utilisent le temps delta. Comment calculer le temps delta en surabondance? Comment calculer la vitesse en utilisant le temps delta?

Mark Fedurin
la source
C11 et C ++ 11 ont également des horloges en nanosecondes: stackoverflow.com/a/36095407/895245 || stackoverflow.com/a/5524138/895245
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Réponses:

18

Le "temps delta" était le temps écoulé entre deux mises à jour de trame (mais il peut également être utilisé dans d'autres contextes; c'est généralement le résultat d'une soustraction de temps).

Vous pouvez obtenir le temps delta dans glut en utilisant la méthode glutGet et le paramètre GLUT_ELAPSED_TIME, ainsi que certaines opérations.

La ligne suivante renvoie le nombre de millisecondes depuis l'appel de glutInit (ou le premier appel à glutGet (GLUT_ELAPSED_TIME)):

int timeSinceStart = glutGet(GLUT_ELAPSED_TIME);

Donc, si vous enregistrez le timeSinceStart actuel à chaque boucle de rendu, vous pouvez connaître le deltaTime en soustrayant l'ancien au nouveau.

int oldTimeSinceStart = 0;

while( ... )
{
     int timeSinceStart = glutGet(GLUT_ELAPSED_TIME);
     int deltaTime = timeSinceStart - oldTimeSinceStart;
     oldTimeSinceStart = timeSinceStart;

     //... stuff to update using deltaTime
}

Vous pouvez également le faire presque de la même manière, en utilisant la bibliothèque ctime C / C ++ avec clock () et l'expression de constante macro CLOCKS_PER_SEC qui spécifie la relation entre un tick d'horloge et une seconde.


Fondamentalement, vous pouvez utiliser deltaTime pour mettre à jour vos mouvements par rapport à ce temps écoulé au lieu d'utiliser une valeur de temps fixe. De cette façon, la vitesse de déplacement de votre personnage devrait être presque la même si votre programme tourne à 60 fps ou s'il tourne à 10 fps.


Voici un petit exemple: supposons que vous vouliez déplacer quelque chose de 10 unités par seconde sur l'axe x. Vous pourriez faire quelque chose comme ça (si deltaTime utilise en effet des millisecondes).

Position.x += 10/1000 * deltaTime;

De cette façon, que votre programme soit mis à jour 2 fois ou 100 fois, 1 seconde plus tard, la position devrait être presque la même, et le jeu est moins impacté par les faibles fps d'un petit ordinateur que s'il utilise des valeurs fixes.

  • Avec des valeurs fixes ==> fps faibles = moins de mises à jour = mouvements lents alors que fps élevés = plus de mises à jour = mouvements très rapides.

  • Avec deltaTime ==> "presque" les mêmes mouvements.


Enfin, vous devriez lire Pas de temps fixe vs Pas de temps variable sur gamedev.stackexchange.

Valkea
la source
Il renvoie des millisecondes sous forme d'entier? Brut et peut-être pas suffisant. J'ai toujours dû utiliser des minuteries spécifiques à la plate-forme, puis j'ai juste évité le GLUT comme la peste car ce n'est pas super pour les jeux.
Sean Middleditch
@Sean, je n'utilise pas non plus GLUT, mais c'était dans le paramètre de la question, j'ai donc répondu en gardant cela à l'esprit;) Cependant, je suis intrigué par votre position en ce qui concerne "l'insuffisance" d'int pour gérer les millisecondes dans les jeux . Un positive intaller généralement jusqu'à 2.147.483.647 si signé et jusqu'à 4.294.967.295 si non signé ... donc même si nous considérons le plus petit, 2.147.483.647 millisecondes est presque 25 jours ... Il devrait être assez suffisant pour gérer la plupart des jeux minuteries et même si cela ne suffit pas, nous pouvons toujours raisonnablement utiliser unsigned int(~ 50 jours) ou même un long long(comme je le fais habituellement).
Valkea
1
@Valkea Le point n'est pas le maximum, c'est la résolution à l'extrémité inférieure. Puisqu'une seule trame à 60 FPS n'est que de 16 2/3 ms, une précision de 1 ms (en représentant des millisecondes sous forme d'entiers) représente une marge d'erreur de plus de 5% - plus que suffisant pour lancer des simulations loin de tout contrôle. Un nombre entier de microsecondes serait supportable, mais les millisecondes sont tout simplement trop grossières.
Steven Stadnicki
Oui, vous avez besoin d'un timing inférieur à la milliseconde pour beaucoup de choses et d'un minuteur haute résolution pour trouver cela, ce que GLUT ne fournit pas (que je sache). Ce n'est pas mal d'écrire juste un petit code de plate-forme à utiliser QueryPerformanceCountersur Windows et gettimeofdaysur la plupart des autres. Vous allez devoir vous salir les mains et viser un peu plus que le dénominateur le moins commun des API de plate-forme, en particulier en C et C ++.
Sean Middleditch
Une telle précision n'est pas utile pour tous les jeux. Cependant, c'est une explication très intéressante qui répond pleinement à mon interrogation sur votre point de vue concernant l'int et les horloges. Je n'avais encore jamais eu besoin d'une horloge de haute précision, mais je suppose qu'il est temps d'approfondir mes connaissances en la matière. Merci;)
Valkea