comment avoir un timing pr un chronomètre [C++/OpenGl] - C++ - Programmation
Marsh Posté le 28-12-2002 à 00:32:50
GetTickCount : renvoie le tps en ms depuis je ne sais pu quoi mais on s'en fout
Donc tu fais un getTickBidule avant, un apres, tu soustrait les deux, tu divises par 1000 et surprise surprise tu as le tps en seconde
Marsh Posté le 28-12-2002 à 00:53:55
le mieux c'est de mettre un timer windows qui se déclenche ttes les secondes, non ?
Marsh Posté le 28-12-2002 à 01:00:57
C'est des fonctions windows uniquement, donc si tu vises nunux ...
Y'a enormement de sites qui les présentent (cherche "classe c++ chronometre" par exemple)
http://www.google.fr/search?q=gett [...] l=fr&meta=
Marsh Posté le 28-12-2002 à 01:03:13
Citation : le mieux c'est de mettre un timer windows qui se déclenche ttes les secondes, non ? |
ben ca depend de ce qu'il veut :
- effectuer une action précise toute les XXX millisecondes => OK
- savoir combien de temps s'est écoulé depuis le bedut de la partie => classe chronometre
Marsh Posté le 28-12-2002 à 09:36:48
merci à vous 3, chrisbk, farib, helloworld
bahhh en fait, j'aimerai en fait me faire un petit tetris en OpenGL....
dc en effet j'aimerais faire decendre mes elements ttes les XX secondes et de plus rapidement au fur et a mesure de la partie..
ms j'aimerais rajouter aussi un petit chronometre en haut à gauche de l'ecran pour savoir combien de tps le joueur à jouer a sa partie .......
dc ds c cas la vs me conseiller une classe chrnonometre ca existe ca ..... savais pas je vais regardé ca...
helloworld merci pr le lien sur google je vais regarder ca pr les 2 ft
nunux ou windows, bahh pr l'instant je fais mon petit projet sous windows , l'ideal est qu'il tourne sous les 2 plateforme ms si c pas possible ou cela me complique .... je me contenterais de zindows ...
Marsh Posté le 28-12-2002 à 09:56:28
Ben utilise un timer alors, pas un chronometre.
L'astuce, c'est de le régler à 100 ms par exemple.
Pour le temps joué : tu incrémentes tous les 10 tics (1 sec)
Pour les niveau + vitesse du jeu :
- si niveau 1 : on descend tous les 10 tics
- si niveau 2 : on descend tous les 9 tics
- si niveau 3: on descend tous les 8 tics
- ...
Marsh Posté le 28-12-2002 à 12:28:19
arf oui ms je me rends compte que les API windows c pas evident ....
par ex
Code :
|
il faut utilisez des variables currency pr enregistrer les tps sur 64 bits ....
ou sinon je peux comme vs l'avez dit qui est amplement suffisant pr moi GetTickCount() pr eviter le pb de la variable currency (qui est pr l'instant une classe pr moi selon l'aide de borland)
ms ce coup ci il faut que j'utilise une variable dword pr stocker le tps fourni pr GetTickCount()
ola ola
je pensais que c'etait plus simple que ca
EDIT : je regarde sur MSDN ms ou ke c dur....
DWORD dwStart = GetTickCount();
// Stop if this has taken too long
if( GetTickCount() - dwStart >= TIMELIMIT )
Cancel();
Marsh Posté le 28-12-2002 à 13:05:08
C'est pas comme ca, car tu fais de l'attente active.
Lance un timer plutot.
Code :
|
J'ai pas testé mais ca devrait coller.
Pour l'exemple, le niveau (g_level) marche en fait a l'envers : plus il est élevé et plus le jeu est facile (lent).
Marsh Posté le 28-12-2002 à 23:07:24
je comprends pas trop ton code
mettons on commence comme tu as lis au level = 0
Code :
|
Bon visiblement qd g_level = 0 ou = 1
on fait descendre a chaque tour la brique
et initialisation ts les 10 tours de total_time
Qd on initialise g_level = 3 avt la fonction par contre
il fut que cout de 1 de 2 et enfin de 3,
quand count=3 >= g_level=3 est VRAI
dc tte les 3 boucles on fait descendre la brique
comme tu as dis on execute de - en - souvent le deplacement quand
g_level est de plus elevé
pr la fonction :
UINT SetTimer( UINT nIDEvent, UINT nElapse, void (CALLBACK EXPORT* lpfnTimer)(HWND, UINT, UINT, DWORD) );
je pense que tu t trompé d'apres
http://msdn.microsoft.com/library/ [...] ttimer.asp
il n'y a que 3 parametres et non pas 4
c comme la fonction kill y en qu'une, ms peut etre que ce st des para optionnel ou tu as mis null
dc pr l'instant tt est ok
ms par contre je ne comprends pourquoi tu utilise une variable total_time qui est soit disant le temps ecoulé depuis le debut alors que tu l'initialise ttes les 10 boucles ....
j'ai voulu tester ton code ds un main() { ton code }
et j'ai malheuresement eu un SIze of 'CALLBACK' is unknown or zero
fnction 'KillTimer' indefini, et symbole idTimer indefini aussi :-(((((((((((
arf je vais arreter maintenant je te pose plein de question surtout que tu n'as peut etre pas trop utilisé cette fonction.....
Marsh Posté le 28-12-2002 à 23:46:37
Pour le SetTimer je me suis pas trompé.
http://msdn.microsoft.com/library/ [...] Timers.asp
faut include <windows.h>
Tu as donné un lien vers les MFC, => classe CWnd, qui encapsule le tout. Le 4° parametre (le 1° en fait) est passé automatiquement, il s'agit du handle de CWnd.
Apparement, t'as pas trop compris comment ca marche.
Code :
|
a partir de la, la fonction TimerProc va etre automatiquement appelee toutes les 100ms, sans rien d'autre a faire.
Donc, au debut du jeu => on lance
Toutes les 100 secondes :
- on ajoute 100 ms au compteur de temps écoulé (total_time)
si on atteind une nouvelle seconde (total_time % 10 == 0)
alors c'est qu'une seconde entiere s'est ecoulee, on met a
jour l'affichage du temps
- on comptabilise le nombres de millisecondes ecoulee depuis
que la derniere brique est tombee (count). En fonction de
cette valeur et du niveau du jeu, on decide ou pas si on fait
tomber la brique d'un cran de plus
niveau 1 : faire tomber toutes les 1 sec => quand count vaut 10
niveau 2 : faire tomber toutes les 0.9 sec => quand count vaut 9
niveau 3 : faire tomber toutes les 0.8 sec => quand count vaut 8
...
L'erreur CALLBACK, ca doit etre parce que t'as pas inclus windows.h
Marsh Posté le 29-12-2002 à 01:28:18
pour mon tetris a moi, g tt fait en programmation évennementielle, c bien pratique (avec c++ builder 6)
Marsh Posté le 29-12-2002 à 02:11:58
Ben la aussi c'est evenementiel.
Toutes les 100ms, WM_TIMER est envoyé.
Marsh Posté le 29-12-2002 à 11:12:50
il faut tout faire en évennementiel
quand on apuye sur une touche il y a un évennement
quand y'a le timer y'a un évenement....
Marsh Posté le 29-12-2002 à 12:27:28
ben normalement c'est deja comme ca que ca se passe
Marsh Posté le 29-12-2002 à 13:20:53
chrisbk a écrit : GetTickCount : renvoie le tps en ms depuis je ne sais pu quoi mais on s'en fout |
cai un nombre de cycles horloges fait par le processeur ...
Marsh Posté le 29-12-2002 à 13:35:30
BotMan a écrit : cai un nombre de cycles horloges fait par le processeur ... |
non ca c'est RDTSC (fonction ASM, je sais pas si dispo en C/C++ de facon std)
Sinon :
GetTickCount
Citation : The GetTickCount function retrieves the number of milliseconds that have elapsed since the system was started. It is limited to the resolution of the system timer |
http://msdn.microsoft.com/library/ [...] kcount.asp
Marsh Posté le 29-12-2002 à 14:07:23
- queryperformance si ta besoin de precision (mais coute en cpu)
- sinon ya aussi timegetime et gettickcount qui fonctionnent tres bien (precision de 10ms)
personellement jutilise jamais de timer je fait simplement comme ca :
Code :
|
comme ca tu execute ta fonction toutes les 1 sec.
Marsh Posté le 29-12-2002 à 16:45:31
oui en fait on peut faire a peu pres la meme chose avec ces 3 fonction : timer, gettick et le performance
oui je sais que le performance occupe plus le proc ms est plus precis ms le problème c qu'il faut savoir utiliser une variable de type currency pour stocker le temps renvoyer par la fonction performance
sinon pr le normal gettick normal, bizare que tu utilise un int pr stocker la valeur de retour de GetTickCount();
prototype d'apres http://msdn.microsoft.com/library/ [...] kcount.asp
DWORD GetTickCount(void);
helloworld
Citation : Toutes les 100 secondes : |
je pense que tu voulais dire toutes les 100 millisecondes
sinon je suis content, j'ai enfin compris ton code merci pour ton explication
je savais pas du tout a quoi servait total_time, cela permet de connaitre le temps de la partie en sec. Ce qui peut etre pas mal, à partir de la je peux faire defiler des chiffres pour faire un chronomètre (chrono.affiche() par exemple).....
pour ce qui est du count, j'avais compris mais je savais pas que cela s'executer toutes les 100 millisec .... apres une fois que count=1 on peut diminuer le fameux 100 millisec du fameux settimer (3ème parametre)
ton code est pratique comme tout il est utilise pr le chrono et et le deplacement, donc je pense c'etait juste pour ces 2 actions dont j'en avais besoin...
mais pourquoi t'es tu embeté a faire ceci et non pas directement
Code :
|
ma synataxe n'est pas du toute bonne, mais utiliser plusieurs ne serais ce pas plus simple
d'apres le lien que tu m'as donné (dans les exemples)il utilise le 2ème parametre de SetTimer pour identifier le timer et pour tuer le timer et non la valeur de retour...
je ne sais pas trop je me suis servis des exemples mais ils sont un peu brouillons
ton code me mets tjrs 2 erreurs
Code :
|
Marsh Posté le 29-12-2002 à 20:21:23
Citation : personellement jutilise jamais de timer je fait simplement comme ca :
|
eh bien tu devrais !
car c'est exactement ce que tu fais, sauf que :
- tu fais de l'attente active et c'est _MAL_
- t'es moins précis
Citation : mais pourquoi t'es tu embeté a faire ceci et non pas directement
|
POur 2 raisons :
- pourquoi utiliser 2 timer quand 1 seul suffit ?
- avec 1 seul timer, je suis synchro
- avec 2, tes 2 timer font tres certainement se décaler. Ainsi, la brique peut tomber, puis 20 ms apres le temps est mis à jour, puis plus tard la brique tombe et 70 ms apres le temps est maj ... Ton temps ne va pas etre changé en même temps que le lignes évoluent.
Pour le idTimer, ben met DWORD a la place de UINT, ou au pite unsigned int (UINT = unsigned int).
Pour le CALLBACK, c'est bizarre ... je sais pas trop. Essai de l'enlever et ragarde ce qu'il te dit de mettre ...
Marsh Posté le 29-12-2002 à 23:32:48
oki pr le decalage si on veut etre perfectioniste
pr ce qui de le l'erreur de idTimer c'est resolu en le declarant de le main au debut
pour le callback, c'etait resolu
mais maintenant y a toujours : declaration syntaxe error
Code :
|
Marsh Posté le 30-12-2002 à 00:19:36
HelloWorld a écrit :
|
heu, parfois tu as d'autre truc a faire dans le jeu donc oblige de boucle sans cesse
Marsh Posté le 30-12-2002 à 04:08:27
Ca ne concerne pas l'exemple Tetris mais
voici ce que je faisais pour ma boucle de jeu :
Code :
|
ca veut dire que quand l'applicatione est active elle va utiliser tout le CPU disponible en fonction de la vitesse de rafraichissement de l'ecran.
J'ai egalement deux temps: le temps de la simulation et le temps systeme. Le moteur de jeu est une boite noire a qui je fournis des informations de temps par le update(GranularityConst).
Je lui donne une constante pour que la physique et la logique soit independante du frame rate et du temps d'execution reel de la fonction.
Ainsi je peux accelerer le jeu en lui passant un temps double ou le rallentir en divisant le temps ecoule par deux.
Comme le framerate et la granularite temporelle de la simulation sont deux valeurs independantes, je suis oblige de synchroniser les deux, en calculant en fonction du temps ecoule a la frame precedente de quelle duree effective je dois mettre a jour le monde pour la frame suivante.
LeGreg
Marsh Posté le 30-12-2002 à 12:20:00
ola ola cela me semble bien compliquer tt ca legreg
par rapport a ce que me proposait HelloWorld malgré ton explication
cependant je vais me pencher sur ton code ......
HelloWorld, j'ai mis la fonction dans le main or ce n'est pas pas conseillé
mais en contre partie, j'ai 2 nouvelle erreur :
Error: conseil.cpp(36,54):Cannot convert 'void (__stdcall *)(void *,unsigned int,unsigned int,unsigned long)' to 'int (__stdcall *)()'
Error: conseil.cpp(36,54):Type mismatch in parameter 'lpTimerFunc' in call to '__stdcall SetTimer(void *,unsigned int,unsigned int,int (__stdcall *)())'
on m'a parlé de win32, qu'il fallait y etre absolument pour que le timer fonctionne ....
Pour cela il faut a ce qui parait remplacé main() par WinMain() mais cela ne change rien du tout.....
Nb : je rappelle, je compile sous BorlandC++5.02
Marsh Posté le 30-12-2002 à 15:40:12
la fonction que tu donnes a SetTimer doit avoir un prototype precu, que tu ne respecte visiblement pas. Cf msdn pour savoir le proto exact
Marsh Posté le 30-12-2002 à 20:05:38
weed a écrit : ola ola cela me semble bien compliquer tt ca legreg |
c'est pas indispensable pour ton tetris
l'important pour toi c'est que les pieces descendent toujours
a la meme vitesse quelle que soit la rapidite de la machine,
que il n'y ait jamais de mouvement de pieces qui ne soit
retranscrite a l'ecran (parce que jouer a tetris en aveugle
ce n'est pas facile) et puis aussi qu'il y ait une faible latence entre la commande du joueur et le mouvement effectif a l'ecran.
LeGreg
Marsh Posté le 31-12-2002 à 20:35:36
oui exact greg
qu'est que ca me broute des que je change de machine j'ai tjrs des pb de biblio
bon je vais reflechir au pb de timing qd je serais chez moi avec l'adsl
bon merci a vous ts et bonne année
Marsh Posté le 27-12-2002 à 23:08:38
voila je viens de terminer ma classe chiffre, je peux enfin afficher des chiffres ds ma fenetre graphique sous opengl....
j'aimerais cree un timer pr cronometrer chaque partie de mon nouveau jeu tertris
on m'a conseillé ms j'ai pas pu avoir de reponse
--> GetTickCount()
--> QueryPerformanceCounte()
sous OpenGL ....
Quelqu'un saurait les utiliser ???
Ou connaisez vous une autre commande (un genre de sleep(1s) /timer) en C++ ou en OpenGL/Glut
NB mon compilateur -> borland 5.02 sous windows