Thread.sleep() funktioniert nicht korrekt

d4rkY89

Mitglied
Hallo.
Ich habe hier ein kleines Problem. Und zwar programmier ich gerade ein kleines Lernspiel. Die Animationen werden durch einen Thread ausgeführt, welcher am Ende ein paar Milisekunden mit der Funktion "Thread.sleep()" warten soll um auf eine bestimmte FPS zu kommen. Dieser "Timeout" wird dynamisch Berechnet. Der Wert stimmt auch soweit immer. Das einzige Problem ist nun, dass der Thread beispielsweise 20 Milisekunden warten soll, statt dessen aber 32 ms wartet. Auch wenn ich manuell 20 ms an Thread.sleep(20) übergebe, messe ich an der Stelle einen Timeout von 32 ms. Dadurch wird das Ganze eben wesentlich langsamer Abgespielt.

Hier habe ich mal die Stelle rauskopiert, an der der Thread warten soll:

Java:
long totalTimeOut = Math.round(1000.0d / FPS);
long timeOut = totalTimeOut - (System.currentTimeMillis() - startTime);
System.out.println("Timeout: " + timeOut);  // Bei 50 FPS kommen hier 20 ms raus (momentan gibts nicht viel zu Berrechnen deshalb der ziemlich genaue wert von 20 ms bei 50 FPS)

long time = System.currentTimeMillis();
if(timeOut > 0)
	Thread.sleep(timeOut);

System.out.println("Total Timeout: " + (System.currentTimeMillis() - time));  //Hier messe ich allerdings 32 ms

Vielleicht hat ja jemand von euch eine Idee, woran es liegen kann. Andere Lösungsvorschläge, an dieser Stelle eine Pause von [timeOut] ms einzuhalten sind mir auch Willkommen.
Vielleicht kann mir ja jemand, der Erfahrung mit 2D Animationen hat, diese mit mir teilen und mir erklären, wie er das Animationsproblem löst. Da ich dachte es wäre ziemlich unschön für jede Bewegung, die in Kraft tritt, einen Thread zu erstellen hab mich eben dafür entschieden das ganze in einem Thread zu bearbeiten. Für mich ist das jedoch Neuland und deshalb würde ich gerne wissen, die man so etwas relativ schön und sauber macht.
 
Zuletzt bearbeitet:
Howdie.

Zum Thema Thread.sleep(long timeout):
Dieser Aufruf bedeutet keineswegs, dass exakt die Zeit des Timeouts gewartet wird - es handelt sich nur um die Mindestzeit. Der Aufruf von sleep ist eine höfliche Bitte an den Thread-Scheduler, den gewünschten Thread möglichst nah an der Mindest-Zeit wieder Laufzeit zuzuweisen. Es kann im schlimmsten Fall sogar vorkommen, dass dein Thread für die nächsten 10 Minuten (i.d.R. natürlich nicht, aber die Botschaft soll klar sein) nicht mehr läuft, falls beispielsweise die Priorisierung dementsprechend eingestellt ist.

Gibts es bei Java2D echt keine Methoden, um die FPS einzustellen? Ich hab auf dem Gebiet leider keine Erfahrung.

Gruß und viel Erfolg
miffi
 
Ihr könnt mal versuchen die Runnable durch nen TimerTask aufzurufen, ich weiß zwar nicht ob das viel besser hinhaut, da ich ihm sehr selten benutze, aber möglicherweiße ist es besser.
Wobei das mit den dynamischen TimeOut auch so eine Sache ist, da ich oft gehört habe, dass die MS/NS-Rückgabewerte von Java (vom OS abhängig) auch recht ungenau sind.

PS: Statt Thread.sleep lieber TimeUnit.MILLISECONDS.sleep(long);, rechnet bei einen anderen Enum-Feld um.
 
Hey danke für die Infos.
Ich habe im Internet was ganz Nettes gefunden, womit man den Umgang mit Java 2D relativ gut lernen kann. Jedenfalls ist es genau das, wonach ich gesucht habe :)

Hier habe ich mal den Link für alle, die vielleicht auch in Zukunft lust haben ein 2D Spiel zu programmieren. Das ganze wird anhand des Klassikers "Space Invaders" gezeigt ;)

Das ganze kann man sogar gut verstehen, wenn man sich nur den Source-Code durchließt, welcher gut dokumentiert ist.

> Klick mich <
 
Zurück