Pour une boucle de jeu de base, vous exécutez une boucle while, dans laquelle vous obtenez le temps à l'aide de nanoTime (), déterminez le temps écoulé depuis la dernière image, puis mettez à jour votre état de jeu et le rendu.
À l'aide de http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#nanoTime%28%29 , vous pouvez interroger le temps écoulé. Fondamentalement...
public static void main(String [ ] args)
{
long current_frame_time = system.nanoTime();
long last_frame_time = current_frame_time;
while(gameIsRunning)
{
last_frame_time = current_frame_time;
current_frame_time = system.nanoTime();
long timeTaken = current_frame_time - last_frame_time;
//update and render game here
}
}
Cette méthode de base peut être améliorée, par exemple http://www.koonsolo.com/news/dewitters-gameloop/ et http://gafferongames.com/game-physics/fix-your-timestep/ .
Vous pouvez également créer une minuterie et définir cette minuterie pour exécuter votre mise à jour et le rendu toutes les X millisecondes. Mais, il y a des inconvénients à construire une gameloop comme ça.
Selon http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html : " Correspondant à chaque objet Timer est un thread d'arrière-plan unique qui est utilisé pour exécuter tous les minuteurs les tâches du minuteur doivent se terminer rapidement. Si une tâche du minuteur prend trop de temps, elle "monopolise" le fil d'exécution des tâches du minuteur. Cela peut, à son tour, retarder l'exécution des tâches suivantes, qui peuvent "se regrouper" et exécutez-les en succession rapide lorsque (et si) la tâche incriminée se termine enfin. "
Selon http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html#scheduleAtFixedRate%28java.util.TimerTask,%20java.util.Date,%20long%29 : " Dans une exécution à taux fixe, chaque exécution est planifiée par rapport au temps d'exécution planifié de l'exécution initiale. Si une exécution est retardée pour une raison quelconque (comme la récupération de place ou une autre activité en arrière-plan), deux exécutions ou plus se succéderont rapidement. "rattraper". À long terme, la fréquence d'exécution sera exactement l'inverse de la période spécifiée (en supposant que l'horloge système sous-jacente à Object.wait (long) est exacte). "
Étant donné que vous ne savez généralement pas à l'avance combien de temps prend une boucle de jeu, le réglage d'une minuterie pour exécuter votre boucle de jeu toutes les X millisecondes (en fonction de la fréquence d'images cible) pourrait conduire à quelques images groupées, qui s'exécuteraient chaque fois qu'une image est terminé au lieu de la planification d'un cadre. Lorsque cela se produit ... pourquoi utiliser une minuterie en premier lieu?
Maintenant, ne vous méprenez pas, le minuteur n'est pas une mauvaise classe, mais il est généralement mieux adapté aux petites tâches qui doivent être effectuées périodiquement ou à un certain moment, par exemple, un client de messagerie peut vouloir vérifier les nouveaux messages tous les 5 minutes, ou un compteur peut être décrémenté chaque seconde pour afficher un compte à rebours avant le début d'une course.
Je ne mettrais pas la boucle principale dans une minuterie. Je ferais plutôt une boucle «while» qui traite chaque image, puis j'utiliserais une sorte de fonctionnalité de chronométrage (cela ressemble à Java qui serait System.nanoTime) pour calculer le temps écoulé depuis la dernière image / dernière itération de la boucle.
Certains langages sont des exceptions ici (par exemple, JavaScript, ActionScript) parce que ces langages fonctionnent dans un environnement qui a une boucle principale implicite à laquelle se connecter (par exemple, le navigateur, Flash Player) mais cette exception ne s'applique pas à Java.
la source