J´ai un tit souci et si quelqu´un pourrait m´aider ce serait vraiment cool.
dans mon jeu, je dois être à plus de 300 images/sec, et je voudrais le rabaisser à environ 60 ou une autre valeur.
Sachant que le programme tourne sous opengl avec glut, et que je contrôle les entrées du clavier, il faudrait donc coordonner l´affichage et la gestion des touches, et rabaisser tout ca à environ 60 images par secondes.
Je programme en C ou C++, comme vous voulez par contre je n´utilise pas les fonctions SDL, et oui ca marche pas encore chez moi ! !!!
bah, SDL n´est pas obligatoire hein...
Pour controler ton FrameRate, je crois que ya un tutos de NeHe là dessus, mais en Win32, or toi tu utilises GLUT, yaurait pas une fonction GlutTimer() par hazard ?
encore plus simple, laisse tourner ton jeu avec le max de FPS ( qu´est-ce que vient faire la gestion des touches là dedans ? . ..) : l´utilisateur a TOUJOURS la possibilité de forcer la synchro verticale via ses drivers.
A LGV> Non mais le problème, c´est que la vitesse d´affichage change en fonction de la puissance de l´ordinateur.
Donc puisque j´ai changer mon pc il y a pas longtemps, si je le met sur d´autres ben le jeu va être beaucoup trop lent an niveau des déplacements et de l´affichage.
Donc il faudrait que je stabilise le frame rate afin que le jeu tourne à la même vitesse sur toutes les machines.
En ce qui concerne les déplacement aussi ca joue un rôle important car chez moi je suis obligé de diminuer les valeurs de variation des objets du jeu sinon ils se déplaceront trop rapidement.
A gollumkawder> J´ai chercher sur le net mais je ne trouve pas grand chose sur le timer de glut ! !!
Même si j´en suis encore à SDL, j´ai eu le même problème que toi alors j´ai codé ma propre classe gérant le nombres de boucle par seconde..
Tu prends le temps en début de boucle, et à la fin de la boucle tu reprends le temps, et si la différence entre les deux temps n´est pas égale à ce que tu voudrais ( exemple, pour 60fps il faudrait que chaque boucle prenne environ 16.6 ms), tu attends en faisant une autre boucle à l´intérieur de l´autre où tu reprends le temps à chaque fois jusqu´à ce que la différence soit égale à ce que tu voudrais.. là tu quittes la seconde boucle, résultat les boucles vont toutes faire environ 16.6 ms et même sur un ordi puissant tu auras la même vitesse que sur un ordi moins puissant..
Bon, je n´sais pas si ça a été clair et ce que je propose n´est sans doute pas très optimisé et doit être assez " primitif", mais c´est un moyen simple de contrôler ce genre de choses..
argh l´erreur classique !
Il est très important ne pas être dépendant du framerate ! Alors lorsque tu calcules des déplacements tu dois impérativement les effectuer en fonction du temps écoulé entre 2 frames, ce qui te permet d´avoir un comportement quasi identique quelle que soit la machine cible.
exemple :
NouvellePosition = AnciennePosition + Vitesse * dt;
dt = TempsFrameCourante - TempsFramePrecedente;
et vi, faut intégrer numériquement plutot que de betement incrémenter... on la retrouve souvent cette question/erreur, faudrait pouvoir foutre des " post-it" de forum
Article très interessant à ce sujet:
http://www.nofrag.com/2004/oct/23/14529/
Ca parle de moteur physique, mais y un une parti très instructive sur le temps dans le jeux video
bonne lecture
Voila un exemple de code trouver sur libsld.org ca explique trés bien le prb;
Main()
{
/ //blabalab
while(done==true)
{
SDL_Delay(TimeLeft());
}
}
Uint32 TimeLeft(void)
{
static Uint32 next_time = 0;
Uint32 now;
now = SDL_GetTicks();//obtenir le temps courant
if ( next_time < = now )
{
/ *Pas la peine d´attendre passons vite à la prochaine frame*/
next_time = now+TICK_INTERVAL;
return(0);
}
/ *sinon on attend un certain tps*/
return(next_time-now);
}
Ce qui revient au propos de Altonfrére.
absolument pas, vu qu´ici tu " delayes" tout le programme jusqu´à ce que le temps souhaité soit écoulé ( TICK_INTERVAL) : tu stalles tout ton programme pour attendre betement... Nous on parle d´effectuer en permanence les calculs, mais de tout paramétrer en fonction du temps
je ne répond pas au problème de synchronisation de l´entré, sortie, tenmps etc... mais à cette horreur de conker ( désolé) :
" attends en faisant une autre boucle à l´intérieur de l´autre où tu reprends le temps à chaque fois jusqu´à ce que la différence soit égale à ce que tu voudrais"
c´est horrible comme méthode, ça veut dire qu´un programme de merde qui n´a besoin que de 5% du CPU va utiliser en permanance 100% des ressource parce que tout ce que le système lui passera de ressource processeur, il l´utilisera alors que s´il se mettait correctement en attente ça serait nettement plus sympatique pour le reste du système.
Autant pour moi je parlais pas de la meme chose . .
oui en effet le problème n´est pas le même, il n´y a aucun délai, attente ou système de synchronisation à utiliser. Pour reprendre plus en détail l´exemple que je donnais + haut :
while(!gEndOfGame)
{
TimeFrame = GetTempsCourant(); / / dans l´unité que tu veux ( s, ms, us . ..)
FrameMove(TimeFrame-TimeLastFrame);
RenderFrame();
TimeLastFrame = TimeFrame;
}
/ / Déplacements des objets en fonction du temps écoulé
FrameMove(float _dt)
{
Objet.Position.X += Vitesse.X * _dt;
Objet.Position.Y += Vitesse.Y * _dt;
}
si la vitesse est exprimée en unité par seconde ( pixels, mètres etc...) dt doit être exprimé en secondes donc 30 ms donnera 0.03 etc.. Et les positions représentées sur des float.
Ce qui permet d´avoir un déplacement " constant", sans ralentissement. Seul problème souligné dans l´article qu´indique manest2, l´anticipation sur les déplacements. En cas de ralentissement trop important ( un autre processus qui prendrait tout le temps CPU par exemple, ou l´application qui passerait en mode idle, les déplacements vont être mis à jour après quelques secondes et peuvent donner des résultats non attendus, si la détection de collisions n´est pas bien construite.
Solution, calculer les collisions en fonction du vecteur direction et non par simple calcul sur la position. Cela revient à détecter l´intersection du vecteur direction et des objets de la scène et voir à quel dt la collision peut éventuellement arriver. Si le dt de la frame est < à celui de la collision c´est bon sinon il y a collision et donc il faut en prendre compte pour ne pas effectuer les déplacements.
C´est bien confus tout ca
, mais bon ce permet de voir des points de vue différents.
Donc alors ce que j´ai trouvé d´intéressant serait donc de gérer les déplacement numériquement.
Exemple:
NouvellePosition = AnciennePosition + Vitesse * dt;
dt = TempsFrameCourante - TempsFramePrecedente;
Ok justement j´en suis la dans mon prog car je pars en fait de forces apliqués sur un solide ( une voiture) et qu´on peut diriger avec les touches du clavier. Lorsqu´on appui sur les touches on appliquera une force sur la voiture et ainsi elle évoluera.
Bref pour passer d´un état de force à l´acceleration j´utilise la 2eme loi de Newton a=F/m, il faudrait que j´intégre celle-ci afin d´obtenir la vitesse de l´objet et puis de refaire une autre inetgration afin d´avoir la position de l´objet dans l´espace 3D.
Donc je pourrais afficher l´objet soit avec la derivée seconde ( qui est la position) en utilisant la formule que j´ai mentionné juste au dessus
NouvellePosition = AnciennePosition + Vitesse * dt;.
Mais alors il faut que je regle le probleme du framerate qui change au cours du jeu, il faut que j´arrive à calculer le temps deltaT entre 2 frames, et si possible rabaisser le framerate(afin de ne pas utiliser toute la puissance du processeur).
Mais je me pose une autre question également c´est comment faire pour obtenir la vitesse de la voiture en intégrant l´accélération ( a en m/s^2), car en maths ca va je vois mais comment retranscrire ca en code???
cette ligne suffit pour faire le calcul :
New_Speed = Old_Speed + deltaT * a;
oui ! c´est une intégration numérique, et dans ton cas, que tu passes de a à v ou de v à p ( a acc, v vel, p pos) tu integres par rapport à t, donc la formule reste la meme.
si ton appli est destiné qu´a windows utilise l´api gettickcount ( qui s´ecoule donc à la meme vitesse sur tout les pc)
multimedia timer ! ! y´a que ça de vrai ![]()
rien de special a ajouter pour l erreur courante :
ne faire de mouvements en pixels/frame mais en pixels/seconde.
pour la physique, toute la mecanique peut etre utilisee.
l equation de base est
( sigma)forces = ma
a partir de la, tu peux faire des mouvements realistes. les derivees sont souvent precalculees facilement.