PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : awt, Grafik ruckelt



BlueJay
23-10-2007, 17:46
Hallo Leute,

habe hier eine Animation, bei der auf ein Hintergrundbild 25 Bälle gezeichnet werden, die von einem Schlanhgenkopf zum anderen flitzen.

Dabei laufen sie leider nicht flüssig, sondern bei 3 von 4 Läufen gibt es irgendwann einen kurzen Ruckler/Grafikaussetzer, als ob mal so 1-3 Frames ausfallen - kein Flackern!

An der Berechnung der Koordinaten liegt es nicht (werden aus Array gelesen, welches von eine Funktion gefüttert wird), es muss die grafische Darstellung sein.

Codeteil, wird durch paintComponent angesteuert:


void zeige_lauf(Graphics g)
{ int i,j,k;
daten p_data=parent.my_data; // Koordinatengenerator
g.drawImage(buffer,0,0,null); // Hintergrundbild
for (i=0; i<p_data.maxsprites; i++) if (p_data.kugel[i].tcount>0)
g.drawImage(ima[p_data.kugel[i].typ],p_data.kugel[i].x+ofx,p_data.kugel[i].y+ofy,null);

// muss "Vordergrund" sein:
g.drawImage(schlange1,p_data.kx[0]+ofx,p_data.ky[0]+ofy-16,null);
g.drawImage(schlange2,p_data.kx[p_data.teiler]+ofx,p_data.ky[p_data.teiler]+ofy-16,null);
}


Anzahl Kugeln: 25 (ruckelt auch ab und zu bei 16)
Durchmesser 32px, kreuz und quer über Hintergrundgrafik verteilt
Hintergrundgrafik: 640x480, BufferedImage
Refresh-Rate: 50ms

Wo kann man da noch optimieren?

so long,
BlueJay

mehlvogel
24-10-2007, 17:41
Läuft das ganz doppelt gepuffert ab? Falls nicht schau im Netz mal nach Double Buffering - ich kann dir leider grad keine Links oder Codebeispiele geben...

bischi
24-10-2007, 20:10
Ich hätte da nen Link (gleich der oberste): http://homepage.sunrise.ch/mysunrise/dominikbischoff/tutorials_java.html

MfG Bischi

BlueJay
25-10-2007, 08:07
Laut Beschreibung soll paintComponent double-buffered ablaufen, es flackert ja auch nix. Der Bursche lässt nur ein paar Frames aus.

Zur Sicherheit habe ich auch eine BufferedImage-Variante ausprobiert (klassisches Double Buffering), der Effekt ist derselbe.

Aber es ist immer noch so: eine Zeitlang läuft alles flüssig, dann stockt die Animation, danach geht es für einen etwas längeren Zeitraum flüssig weiter.
Reduziert man die Anzahl Bälle, stockt sie später.
Die Berechnung selbst kommt mit dem Zeittakt mit: nach Weiterlaufen der Ani sind die Koordinaten zeitsynchron zum Startpunkt.
Eine weitere Verbesserung erhält man, wenn die Java-Application die einzige Desktop-Anwendung ist.

Aber es kann doch nicht sein, dass ein 1GHz-Rechner mit NVidia-Karte langsamer läuft als ein über 20 Jahre alter Amiga-2000 mit 4,7 MHz oder ein als ziemlich lahm bekanntes Handy, was zumindest alle Frames bringt!

Ich werde noch versuchen, die Grafiken zu verkleinern, ist aber schade drum.

Damit hat die Java-Animation dann Javascript-Niveau erreicht. :(

bischi
25-10-2007, 18:28
Schau dir mal den Speicherbedarf an! Ich hatte mal ein ähnliches Problem, bei welchem ich noch Handles auf ein Bild hatte, welches dann nicht aus dem Speicher entfernt wurde...

MfG Bischi

BlueJay
27-10-2007, 06:34
Die Bilder selbst werden mal wieder nur 1x erzeigt, dann vom Start bis zum Programmende gebraucht, dazu gibt es die statische Variable grafikpanel.
Ich hoffe mal, dass die wiederholte Anwendung von drawImage auf dem offscreen-Image buffer und Schieberei des buffer auf das Grafikpanel nicht irgendwelchen Unsinn anrichtet.

Aber mit Aufräumarbeiten scheint das Ganze irgendwie zu zun zu haben.
Ich habe das Panel versuchshalber um ca. 30% verkleinert, jetzt ruckelt's nicht mehr.
Gleichzeitig entfielen die halbtransparenten Hintergründe, die schon in einigen Browsern das entsprechende JS enorm ausbremsten.

Noch was:
Ich arbeite in einer Application, male mit paintComponent auf ein Panel, weil es mir sonst die GUI zerhaut (kein Menu mehr).
(paint? Gut, dass wir drüber gesprochen haben! Was ich da sah, war der Grund, mich vor ca.10 Jahren für JS zu entscheiden)

Hat mich auch etwas Zeit gekostet, bis ich merkte, dass Swing und Canvas unvereinbar sind, weil Menu und Canvas ja einzeln funktionierten.

Ich denke, ich muss mich damit abfinden, dass Java kein C++ ist...

@bischi: Deine Seite werde ich mir mal näher betrachten :)

so long,
BlueJay

bischi
27-10-2007, 08:00
Hat mich auch etwas Zeit gekostet, bis ich merkte, dass Swing und Canvas unvereinbar sind, weil Menu und Canvas ja einzeln funktionierten.

Hää? Also bei mir läuft das... Siehe http://homepage.sunrise.ch/mysunrise/dominikbischoff/projekte_code.html und da das JPicIt-Programm (auch wenn das Programm noch weit weg von perfekt ist und ich aktuell keine Zeit habe, das zu ändern :D).

Das es - wenn du es verkleinerst - zu keinen Problemen mehr kommt, tönt für mich arg nach Speicher... Eventuell brauchst du auch mehr, als dir deine JVM zur Verfügung stellt (die Grenze ist da standardmässig recht klein gesetzt - 64 Mega oder so...). Dann wird dann vermutlich auf HD ausgelagert oder so...

MfG Bischi

PS: Ich bin extrem froh, dass Java kein C++ ist - C++ ist grauenhaft zum programmieren :D

anda_skoa
27-10-2007, 11:02
Das hört sich nach einer Verzögerung an, die durch den Garbage Collector verursacht wird.

Eventuell hilft es was, den GC öfter mal explizit anzuwerfen.

Ciao,
_

BlueJay
28-10-2007, 16:52
Hää? Also bei mir läuft das...

Stammt von der Sun-Seite, u.a. hier:
http://forum.java.sun.com/thread.jspa?threadID=403637&messageID=1764422
(ist das 1. aus einer langen Reihe)
Wie gesagt, bei gleichzeitigem Gebrauch haben immer ein paar Gadgets oder der Canvas gefehlt.



Das es - wenn du es verkleinerst - zu keinen Problemen mehr kommt, tönt für mich arg nach Speicher...


Derzeitiger Verbrauch:

Java VM: ummi 400k
Java RSS: ummi 56-57k
(Variante mit DoubleBuffering)

Ich denke mal, dass Andaskoa mit der garbage Collection ziemlich richtig liegt.



PS: Ich bin extrem froh, dass Java kein C++ ist - C++ ist grauenhaft zum programmieren :D
Aber stressen kann man das Zeuch, stressen!
Canvas allein 800x600 und alles voller Flugkörper(60Stück?)! Auch bei der Collision Detection brauchte ich nicht zu hudeln. Und nix ruckelt. Leider nur X11-fähig :rolleyes:

so long,
BlueJay

BlueJay
04-11-2007, 15:48
Also, abschließend ist zu sagen, dass das ganze Zeug mit Heapsize und Garbage Collection nichts gebracht hat.
Die GC wurde "zwangsausgelöst" bei Neustart der Animation.

Double Buffering im JPanel ist auch nicht der Bringer.

Canvas war, mal davon abgesehen, dass das Menu verkrüppelt war, trotz Überschreiben der update-Methode grausam.

Am schnellsten/flüssigsten ging es noch mit direktem Malen des Hintergrundes und der ca. 40 Kugeln direkt aufs JPanel (paintComponent).

Noch schneller war's natürlich, wenn statt Hintergrundbild ein einfarbiges Rechteck im Hintergrund lag.

Zeitmessung mit dem "blanken JPanel" ergibt nach dem Einpendeln von 500ms auf 20ms in 40 Frames) Werte um 15-20ms mit einzelnen Ausreissern um 100-150ms

Mit den 20ms bin ich eigentlich hochzufrieden, aber mich stören die 100ms-Aussetzer (Ruckler), die scheinbar unvermittelt auftauchen (keine Maus bewegt, keine taste gedrückt).

Dasselbe Bild ergab sich, wenn die GC vor Animationsbeginn ausgelöst wurde.
Die Loop zum Berechnen der Bälle war es ebenfalls nicht, die "Spikes" sind asynchron zu den "Umwegen".

Und nun kommt's:
Die Bälle wurden verdreifacht (von 35 auf 100), die mittlere Framerate sackte auf 30 ms (alles unter 50ms ist akzeptabel), und die 100ms-Spikes waren so gut wie verschwunden!

Ich kapier gar nix mehr!

so long,
BlueJay

BlueJay
05-11-2007, 08:02
... und nun kommt die Endlösung:
alle Sprites static zur Klasse Steuerung gemacht, Spikes sind weg!
(siehe Signatur)