# konstante Geschwindigkeit



## Evolver (31. Jul 2007)

Es geht mir um ein altbekanntes Thema: Jedem ist wohl klar, dass ein Spiel unabhängig von der Rechenleistung auf jedem Rechner gleich schnell laufen sollte. Also ist es meist am einfachsten, alle Bewegungen abhängig von der "Framedauer" (Berechnungen + Neuzeichen) zu machen.

In Java habe ich bislang nur Minispiele geschrieben, wo man das nicht braucht. In C++ habe ich schon Spielchen mit dieser Technik geschrieben, wo ich einfach die Zeit vor und nach Berechnungen und dem Zeichnen ermittle und dann mit der Differenz entsprechend weiterarbeite.

Jetzt habe ich in Java einen Thread mit meiner Programmschleife laufen:

```
/*Pseudocode*/
SPIELETHREAD {
   // ...
   SCHLEIFE {
      startzeit = aktuelleZeit();
      brechneAlles(framedauer);
      myJPanel.repaint();        // die Problemstelle
      framdauer = aktuelleZeit() - startzeit;
      // ...
   }
}
```
Das Problem ist ja, dass repaint() nicht wirklich zeichnet, sondern die JVM nur anweist, bei der nächsten Möglichkeit neu zu zeichnen. Ich könnte also so wie es im moment ist, die Framedauer nur abhängig davon machen, wielange das Berechnen dauert, nicht aber von der benötigten Zeit zum Neuzeichnen.
Wie kann man das Problem lösen? Kann ich irgendwie warten, bis neu gezeichnet wurde oder das Zeichnen direkt erzwingen? Oder würdet ihr mir einen ganz anderen Ansatz empfehlen?



Das zweite Problem bezieht sich auf die Berechnungen, z.B. von Bewegungen. In C++ habe ich mit OpenGL gearbeitet, was bei der Ausgabe sowieso immer float oder double akzeptiert hat. Arbeite ich in Java mit Graphics2D dann brauche ich Ganzzahlen. Wenn ich jetzt bei den Berechnugen (Positionen, Bewegung ...) mit double oder float arbeite, da sich ja z.B. die Position nicht bei jedem Frame um einen ganzen Pixel ändert, muss ich ja beim Zeichen entsprechend casten. Kostete mich das sehr viel Zeit? Gibt es vll. eine bessere Lösung?


----------



## Quaxli (31. Jul 2007)

Zu Deiner ersten Frage: Google mal nach BufferStrategy. Damit könntest Du ein aktives Rendering realisieren und wärst unabhängig von repaint(). Allerdings gibt's BufferStrategy nur für AWT, glaube ich.

[Edit]
Das Casten nach Graphics2D sollte keine Probleme verursachen.


----------



## Evolver (31. Jul 2007)

> Das Casten nach Graphics2D sollte keine Probleme verursachen.


Ich meine nicht das Casten von Graphics zu Graphics2D, sondern das Casten von allen Positionsangaben etc., die als double oder float gegeben sind, zu int. Das können ja sehr sehr viele sein.


----------



## ice-breaker (31. Jul 2007)

Es gibt bei Swing eine Methode um das repainten nicht asynchron ausführen zu lassen sondern synchron, da musste mal googlen, war in einem TechPaper von Sun.


----------



## TrentSteel (3. Aug 2007)

Guck mal hier, ob dir das hilft:

mitglied.lycos.de/digbit/tutorials/eins/Animations%20Grundger%FCst.pdf

und Sourcecode dazu:

mitglied.lycos.de/digbit/tutorials.htm


greetz


----------



## Evolver (3. Aug 2007)

Ich schätze letztere ist ziemlich 1zu1 übernommen aus KillerGameProgramming (oder so ähnlich). Bei diesem Ansatz wird getGraphics() verwendet. Ich habe nun mehrfach gelesen, dass man dies auf jeden Fall vermeiden sollt.


----------



## SlaterB (3. Aug 2007)

wo hast du das gelesen?
falls du hier das Forum oder Grundlagen-Lehrbücher meinst, so ist das einer der besten Hinweise, 
dem man einem blind vorgehenden Anfänger geben kann,

in professionellen Tutorials ist es sicherlich ebenso skeptisch zu hinterfragen,
aber bestimmt auch ein denkbares Modell


----------



## TrentSteel (3. Aug 2007)

Der getGraphics()- Ansatz ist tatsächlich so ähnlich, wie in Killer Game Programming.

Aber die Hauptschleife, auf die es dir hier anscheinend ankommt, ist ein völlig andere.
Wenn du mal reinguckst, kommt sie ohne sleep() aus und läuft immer so schnell wie es der Rechner zulässt, ohne andere
Threads zu blockieren. Ich erziehle damit jedenfalls sehr gute Ergebnisse.

Kann mir denn mal jemand eine bessere Möglichkeit zum Zeichnen geben, als mit getGraphics() und einem BufferedImage?


----------

