Comment faire une timer pour une boucle de jeu?

Je veux chronométrer le nombre de fps, et définir sa limite à 60 et quelle que soit ma recherche de code via Google, je ne comprends absolument pas.

Vous ne devriez pas essayer de limiter le nombre de fps. La seule raison de le faire est si vous n’utilisez pas le temps delta et que vous vous attendez à ce que chaque image ait la même longueur. Même le jeu le plus simple ne peut pas garantir cela.

Vous pouvez toutefois prendre votre temps delta et le découper en tailles fixes, puis conserver le rest.

Voici du code que j’ai écrit récemment. Ce n’est pas complètement testé.

void GameLoop::Run() { m_Timer.Reset(); while(!m_Finished()) { Time delta = m_Timer.GetDelta(); Time frameTime(0); unsigned int loopCount = 0; while (delta > m_TickTime && loopCount < m_MaxLoops) { m_SingTick(); delta -= m_TickTime; frameTime += m_TickTime; ++loopCount; } m_Independent(frameTime); // add an exception flag later. // This is if the game hangs if(loopCount >= m_MaxLoops) { delta %= m_TickTime; } m_Render(delta); m_Timer.Unused(delta); } } 

Les objects membres sont des emplacements Boost afin qu’un code différent puisse être enregistré avec différentes méthodes de minutage. L’emplacement indépendant est destiné à des tâches telles que le mappage de touches ou le changement de musique. Des choses qui n’ont pas besoin d’être aussi précises. SingTick est bon pour la physique où c’est plus facile si vous savez que tous les ticks seront identiques mais que vous ne voulez pas traverser un mur. Le rendu prend le delta pour que les animations se déroulent sans heurts, mais vous devez vous rappeler de le prendre en compte lors du prochain SingTick.

J’espère que cela pourra aider.

Si vous voulez 60 FPS, vous devez savoir combien de temps il vous rest sur chaque image. Dans ce cas, 16,67 millisecondes. Vous voulez donc une boucle qui se termine toutes les 16,67 millisecondes.

Habituellement, ça va (tout simplement): Obtenez des entrées, faites des choses sur la physique, rendez, faites une pause jusqu’à ce que 16.67ms se soient écoulés.

Cela se fait généralement en enregistrant le temps au début de la boucle, puis en calculant la différence à la fin et en dormant ou en boucle ne faisant rien pendant cette durée.

Cet article décrit différentes manières de créer des boucles de jeu, y compris celle que vous souhaitez, bien que j’utilise l’une des alternatives les plus avancées de cet article.

L’heure delta est l’heure finale, moins l’heure d’origine.

 dt= t-t0 

Ce temps delta, cependant, est simplement la quantité de temps qui s’écoule pendant que la vitesse change.

La dérivée d’une fonction représente un changement infinitésimal de la fonction par rapport à l’une de ses variables. La dérivée d’une fonction par rapport à la variable est définie par

  f(x + h) - f(x) f'(x) = lim ----------------- h->0 h 

http://mathworld.wolfram.com/Derivative.html

 #include #include #include #include #pragma comment(lib,"winmm.lib") void gotoxy(int x, int y); void StepSimulation(float dt); int main(){ int NewTime = 0; int OldTime = 0; float dt = 0; float TotalTime = 0; int FrameCounter = 0; int RENDER_FRAME_COUNT = 60; while(true){ NewTime = timeGetTime(); dt = (float) (NewTime - OldTime)/1000; //delta time OldTime = NewTime; if (dt > (0.016f)) dt = (0.016f); //delta time if (dt < 0.001f) dt = 0.001f; TotalTime += dt; if(TotalTime > 1.1f){ TotalTime=0; StepSimulation(dt); } if(FrameCounter >= RENDER_FRAME_COUNT){ // draw stuff //Render(); gotoxy(1,2); printf(" \n"); printf("OldTime = %d \n",OldTime); printf("NewTime = %d \n",NewTime); printf("dt = %f \n",dt); printf("TotalTime = %f \n",TotalTime); printf("FrameCounter = %d fps\n",FrameCounter); printf(" \n"); FrameCounter = 0; } else{ gotoxy(22,7); printf("%d ",FrameCounter); FrameCounter++; } } return 0; } void gotoxy(int x, int y){ COORD coord; coord.X = x; coord.Y = y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); return; } void StepSimulation(float dt){ // calculate stuff //vVelocity += Ae * dt; } 

Il y a beaucoup de bonnes raisons pour que vous ne limitiez pas votre fréquence d’images de cette manière. Une des raisons étant, comme l’a souligné Stijn, tous les moniteurs ne peuvent pas fonctionner à exactement 60 images par seconde, une autre étant que la résolution des timers n’est pas suffisante. parallel sera toujours désynchronisé avec le temps (ils doivent!) en raison d’imprécisions aléatoires, et la raison la plus importante étant que ce n’est pas nécessaire du tout.

Notez que la résolution du minuteur par défaut sous Windows est de 15 ms et que la meilleure résolution possible (en utilisant timeBeginPeriod) est de 1 ms. Ainsi, vous pouvez (au mieux) attendre 16 ms ou 17 ms. 16,6666ms pour une image à 60fps. Comment attendre 16,6666ms?

Si vous souhaitez limiter la vitesse de votre jeu à la fréquence d’actualisation du moniteur, activez la synchronisation verticale. Cela fera ce que vous voulez, précisément et sans problèmes de synchronisation. La synchronisation verticale a aussi ses particularités (comme la surprise amusante qu’une image dure en 16,67ms), mais c’est de loin la meilleure solution disponible.

Si vous vouliez faire cela pour adapter votre simulation à la boucle de rendu, cette lecture est indispensable.

vérifier celui-ci:

 //Creating Digital Watch in C++ #include #include using namespace std; struct time{ int hr,min,sec; }; int main() { time a; a.hr = 0; a.min = 0; a.sec = 0; for(int i = 0; i<24; i++) { if(a.hr == 23) { a.hr = 0; } for(int j = 0; j<60; j++) { if(a.min == 59) { a.min = 0; } for(int k = 0; k<60; k++) { if(a.sec == 59) { a.sec = 0; } cout<