2009-11-14 6 views
0

Mon jeu utilise un calcul d = vt pour le mouvement des objets où t est le temps écoulé depuis la dernière image (une image par boucle). J'utilise SDL et l'essentiel du calcul de minutage est que je crée une instance d'une classe Timer et la démarre. J'appelle GetSeconds() quand c'est nécessaire qui renvoie la différence entre le moment où le timer a été démarré et l'heure actuelle (divisé par 1000 car tout est en millisecondes).Problèmes avec deltaTicks combinés avec une grande vitesse dans une boucle de jeu

Ex:

return (SDL_GetTicks() - m_StartingTicks)/MILLISECONDS_PER_SECOND; 

Après chaque boucle la minuterie est remise à zéro. C'est à dire. m_StartingTicks = SDL_GetTicks() Cependant, j'ai récemment changé cela afin qu'il soit seulement réinitialisé if m_StartingTicks is < SDL_GetTicks, mais il n'a pas résolu le problème.

Cela a été tout de même Hunky Dory jusqu'à ce que j'ai récemment écrit un moteur de jeu pour gérer différents états de jeu et diverses autres choses qui sont utilisées dans ma boucle de jeu principal. Cela a sérieusement amélioré les performances, mais malheureusement chaque itération de la boucle de jeu se produit maintenant en moins de 1 milliseconde donc quand je passe GetSeconds(), 0 est retourné et les choses sur l'écran ne bougent pas.

La façon la plus simple de gérer cela est un simple kludge où si SDL_GetTicks() - m_StartingTicks) == 0 je le change en 1 (comme en 1 milliseconde au lieu de 0). Je n'aime pas vraiment cela, et j'aimerais entendre des suggestions, des corrections, des améliorations, etc.

Si vous avez besoin de plus d'informations, je serais heureux de l'offrir.

Répondre

0

Si vous travaillez à 60 Hz, chaque image doit être d'environ 16 ms. On dirait que vous avez désactivé la synchronisation verticale?

+0

Je ne pense pas que SDL vous permette de désactiver/activer la synchronisation verticale pour un jeu. Je pourrais essayer d'utiliser SDL_HWSURFACE ... – Anonymous

+0

Nope, essayé de marquer à la fois SDL_HWSURFACE et SDL_ASYNCBLIT – Anonymous

+0

A réussi à le faire fonctionner si j'ai appelé reset immédiatement après le passage de GetSeconds() – Anonymous

2

Vous devriez accumuler du temps et mettre à jour votre boucle de jeu à un taux fixe. Consultez ce article pour plus de détails.

0

Il semble que votre code temporisateur ne soit pas correct. Si une image arrive vraiment en moins de 1 milliseconde et qu'elle s'annule, c'est bien, car avec le temps, le temps augmentera et atteindra 1 milliseconde et vous verrez le mouvement, en faisant la moyenne au bon rythme. Il semble que vous essayez de mesurer la durée d'une trame au lieu de mesurer le temps écoulé depuis le même point dans la dernière image, ce qui vous causera des problèmes si la majorité du temps est réellement passée en dehors de votre fonction de mise à jour (par exemple mécanisme vsync).

Il semble également que vous ayez des problèmes d'arrondi: affichez les types de données que vous utilisez. Diviser un petit nombre entier par 1000 tendra à le faire en zéro et vous perdrez toutes les données qu'il contient, même si c'était 999 auparavant. Souvent, il est préférable de le lancer sur un flotteur avant de faire la division.

Questions connexes