Texel
Win32 | Index | Contact

Les Compteurs (et boucle de jeu)

VERSION BETA



La majorité des programmes Windows attendent de recevoir un message pour travailler. Mais pour les applications utilisant des animations graphiques, il faut calculer et afficher en permanence des images même quand l'utilisateur ne fait rien. Il faut donc dans ces cas là remplacer la fonction GetMessage par PeekMessage que nous avons rapidement vu dans le tutorial sur les bases de l'API WIN32 et qui permet d'exécuter un code en l'absence de message.

De plus, pour que les animations aient une vitesse constante et égale sur des machines de puissances différentes, il faut pouvoir afficher les images en fonction du temps. Dans un programme, la boucle de jeu est une boucle qui gère les messages (avec PeekMessage), les entrées de l'utilisateur (joystick…), et qui affiches les images après calcul en fonction du temps. En gros elle contient l'algorithme du programme. Il existe plusieurs fonctions qui peuvent nous servir de compteur pour le temps:


timeGetTime et GetTickCount

Les plus simples sont timeGetTime et GetTickCount. Ces deux fonctions sans argument, retourne le nombre de millisecondes écoulées depuis le démarrage du système d'exploitation. Pour utiliser la fonction timeGetTime, vous devez ajoutez la librairie winmm.lib au projet ( sous Visual). L'inclusion de mmsystem.h ne semble pas obligatoire.
Avec ces fonctions, le contenu de la boucle de jeu est très simple. A l'initialisation, on obtient le temps écoulé depuis le démarrage de l'OS. Puis dans la boucle:

_ On traite les messages Windows avec PeekMessage

_ Ou si pas de message: On lit de nouveau l'heure et si le temps écoulé depuis le dernier rendu de l'image est supérieur à un certain nombre de milliseconde (qui correspond par exemple à 1/60 ième de seconde) on calcul l'emplacement des images et on les affiche. On peut éventuellement avant cette condition, détecter les entrée clavier ou joystick. Pour ceux qui ne le savent pas, le nombre d'images rendu par seconde est appelé fps (de l'anglais frame per second).


le compteur de performance

Il existe aussi une méthode à peine plus compliqué et qui permet une précision plus grande que le milliseconde . Elle utilise le compteur de performance qui est un compteur matériel situé dans les microprocesseurs. Ce compteur à une fréquence qui rappelons le, correspond à un nombre de cycle d'horloge par seconde. A l'initialisation, on obtient la fréquence du compteur avec la fonction QueryPerformanceFrequency. On obtient également le nombre de cycles écoulé depuis un moment X avec la fonction QueryPerformanceCounter et on fera de même dans la boucle de jeu. Puis dans la boucle, on ne compare plus le nombre de millisecondes écoulées mais le nombre de cycle d'horloge écoulé. Pour afficher 60 images par secondes on a auparavant divisé la fréquence de l'horloge par 60. Les deux fonctions se présentent ainsi:

BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency );
BOOL QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount);





Attention: la documentation de l'API WIN32 indique que ce compteur n'est pas présent sur tous les processeurs (mais la doc date un peu et ça a marché sur tous les processeurs Intel et AMD que j'ai testé). Pour éviter les problèmes, détectez la présence de ce compteur (la fonction QueryPerformanceFrequency retourne un BOOL) et en cas d'absence, permettez au programme d'utiliser par exemple GetTickCount.


Conclusion

Lors de l'affichage de chaque nouvelle image, évitez de faire avancer vos animations par des sauts constants (exemple: x = x + 10). Multipliez plutôt vos pas par le temps écoulé depuis le dernier rendu ( x = x + 10*TempsEcoulé). En effet, si vous imposez un rendu toutes les 1/60ème de secondes par exemple, il est possible à un instant (ou en permanance), que votre PC ne soit pas assez rapide pour faire tous les calculs.
Pour finir, notez qu'il est très simple d'afficher les images non pas tous les 1/n ième de secondes, mais dés que le PC peut le faire. Cela permet d'avoir un nombre d'image par seconde variable en fonction de la puissance des machines. Pour que la vitesse de l'animation du jeu soit constante, il suffit de faire comme expliquer plus haut: On utilise le temps écoulé et on enlève la condition qui oblige une fps constant.

Vous pouvez télécharger ici, le code source du même programme avec les trois méthodes.


Version originale: Fevrier 2001
Dernière mise à jour: Octobre 2003
Par Grégory Smialek
www.texel.fr.fm