# Java Spiel auf diversen System unspielabr



## radiac (14. Nov 2009)

Hallo Leute...

ich bin echt verzweifelt. Ich hatte damals schon das Problem, das mein Spiel auf diversen Rechnern, besonders mit Ati Grafikkarten auf sehr niedrigem FPS laufen.

Damals wurde mir gesagt, das ich Direct3D auf false setzen soll damit die Hardwarebeschleunigung abgeschaltet wird. Das lief anfangs auch ziemlich gut. Jedoch wird es immer schlimmer, je mehr man einbaut.
Was ich auch nicht verstehe ist, das ein SPiel doch eigentlich gerade besser laufen soll, wenn die Hardwarebeschleunigung aktiv ist..???

Jetzt sind es nur noch 15 FPS. Auf meinem System waren es zu begin 280 FPS... mittlerweile auch nur noch 60...
Das Spiel läd die Grafiken und rendert sie mit BufferedImages. Habe auch schon das komplette Ding mit Volatile zeichnen lassen... keine Verbesserung.

Was ist denn das nur für ein mist? Das Spiel hat eine Scrollmap. Das gesamt "Bild(PNG)" der Scrollmap ist 2200 x2200 Pixel groß bei einer Farbtiefe von 150... die Größe es Bildes beläuft sich smoit auf 856 kb, was schon sehr klein ist.
Dennoch bekommt es Java nicht gebacken das in einer angenehmen Darstellung zu zeichnen... Habe auch schon die Tilegrößen hin und her probiert... bringt alles nichts....

- Meine Fragen sind jetzt... woran kann das liegen??? (Grafikcode wurde 3 mal exact nach dem Schema der BuffereImage und rendering Methode aufgesetzt... ). In allen möglichen Tutorials und Java Tuts steht es gleich drin... Das heisst, daran liegt es eigentlich nicht.

- Wie macht ihr sowas? Benutzt ihr evt. sogar eine 3D API für 2D-darstellungen?
- Gibt es evt. einen fix für sowas?
- Oder bin ich einfach nur zu blöd?

Ich komm gerade echt nicht weiter...

Was vielleicht auch noch wichtig wäre ist, dass das Spiel im FSEM läuft. Momentan bei einer Auflösung von 800 x600 und 16 Bit. Auch hier hab ich schon 32 Bit und alles mögliche versucht...

Wäre nett wenn mir ein richtiger Java-Checker helfen würde. Ich programmiere erst seit ca. 8 Monaten... vielleicht gibts da ja gute Methoden die ich nicht kenne, damit es endlich überall flüssig und angenehm läuft.


Würde mich auf Hilfe freuen.

Ps: Programmcode posten ist unmöglich, da es über 60 Klassen sind. Wie gesagt, die Bilder werden nach dem ganz normalen BufferedImage Prinzip geladen. Daher denke ich auch, das ein Gamecoder mir vielleicht am besten helfen kann. Aber bin natürlich auch für gute und schlechte Hinweise zu haben .


Viele Grüße Radiac


----------



## Steev (14. Nov 2009)

Wenn ich das richtig verstanden habe, dann zeichnest du ein PNG mit den Ausmaßen 2200x2200?
Java bekommt besonders bei PNG schon ab einer Größe von 640x480 ein Problem das komplett zu zeichnen.
Konvertiere die PNG-Datei zum Beispiel mal in ein GIF und zeichne probiere es dann noch einmal aus. Wenn es dann immer noch nicht korrekt funktioniert. Dann versuche doch einfach mal nur einen Ausschnitt des Bildes zu Zeichnen, ich würde das Bild sowieso nicht als ganzes im Speicher halten sondern es in kleinere Stück á 100x100 Pixel zerhacken und diese dann über eine eigene Methode rendern lassen. So komme ich eigendlich immer zu recht annehmbaren Ergebnissen.
Auf jedem Fall solltest du über VolatileImage rendern. Die Performanceprobleme kommen auch manchesmal dann zu stande, wenn bestimmte Standard-Java-Methoden verwendet werden. In manchen Methoden werden mehrere Objektinstanzen erstellt. Da läuft dann, insbesondere wenn diese Methoden beim rendern aufgerufen werden, der Speicher schnell voll und die Framerate geht in die Knie, weil der Garbage Collector ständig die "toten" Instanzen beerdigen muss .

Falls keiner meiner Ansätze funktioniert, dann kannst du dich ja nochmal melden...


----------



## Marco13 (14. Nov 2009)

Steev hat gesagt.:


> Java bekommt besonders bei PNG schon ab einer Größe von 640x480 ein Problem das komplett zu zeichnen.
> Konvertiere die PNG-Datei zum Beispiel mal in ein GIF und zeichne probiere es dann noch einmal aus.



Hähm? :autsch: An einem BufferedImage erkennt man nicht mehr (direkt), ob es mal ein JPG, PNG oder GIF war. Höchstens indirekt, aber das kann hier evtl.(!) ein wichtiger Punkt sein: Wenn das Bild transparente Bereiche enthält, kann es u.U. langsamer sein, als ohne. (Und bei so einem Spiel muss man davon ausgehen, DASS transparenzen gibt). 

Ansonsten kann man da aber kaum was dazu sagen. Wenn es zu langsam ist, kann das SO viele Gründe haben... von A wie "Antialiasing angeschaltet" bis Z wie "Zeichenmethode ineffizient" ... Den Code hier posten kannst du nicht, aber wenn du ihn compilierbar in ein ZIP packst und irgendwo hochlädtst, findet sich vielleicht jemand, der sich das mal genauer ansieht (das soll jetzt aber kein Versprechen meinerseits sein (und DAS jetzt kein dfinitives Ausschließen  ))


----------



## Steev (14. Nov 2009)

Marco13 hat gesagt.:


> Hähm? :autsch: An einem BufferedImage erkennt man nicht mehr (direkt), ob es mal ein JPG, PNG oder GIF war. Höchstens indirekt, aber das kann hier evtl.(!) ein wichtiger Punkt sein: Wenn das Bild transparente Bereiche enthält, kann es u.U. langsamer sein, als ohne. (Und bei so einem Spiel muss man davon ausgehen, DASS transparenzen gibt).



Genau das ist ja der Punkt, wenn ein PNG geladen wird, dann wird ein ARGB-BufferedImage erzeugt, egal ob der Alpha-Kanal genutzt wird oder nicht.
Daher sollte man entweder auf der Java-Seite oder mittels Dateityp festlegen, dass nur die tatsächlich genutzten Kanäle auch verwendet werden.


----------



## Marco13 (14. Nov 2009)

OK, war mir da nicht 100% sicher: Neulich hab' ich PNGs geladen, die dann nur 24 bit und Type "CUSTOM" hatten :autsch: Aber die kamen nicht aus einer Datei, sondern aus einem Byte*InputStream... hing vielleicht daran? ???:L :bahnhof: Aber wie gesagt: Das ist eine von SEHR vielen möglichen Ursachen. (Ob GIF da eine Abhilfe wäre? 256 Farben, und möglicherweise AUCH Transparenz(!) ... müßte man sich genauer ansehen...)


----------



## Steev (14. Nov 2009)

Marco13 hat gesagt.:


> Ob GIF da eine Abhilfe wäre? 256 Farben, und möglicherweise AUCH Transparenz(!) ... müßte man sich genauer ansehen...



Man sollte auf jedem Fall einmal probieren die Anzahl der Farbe zu verringern. Ich hatte neulich ein ähnliches Problem bei dem ich dann einfach das große Bild in mehrere Tiles aufgeteilt habe. Für die einzelnen Tiles habe ich dann, je nachdem was drin vorkam entweder gif mit verringerter Farbtiefe (+ Palette) verwendet und nur für die Tiles, wo es unbedingt sein musste png mit Alphakanal.

Zwischen dem Alpha bei gif und png ist ja noch zusätzlich der Unterschied, dass bei PNG Alphawerte von 0-255 unterstützt werden, bei gif hingegen wird nur 0 oder 255 unterstützt, dazwischen gibt es nichts. Das ist von daher dann schneller, weil dann entweder der Pixel übersprungen wird, oder eben gezeichnet wird.

Performanceprobleme kann es aber auch schon dann geben, wenn man zu viele Java-Zeichenmethoden verwendet. drawImage geht ja noch relativ schnell, aber die sonstigen draw- und fill-methoden kann man vergessen. Das wird erst schneller wenn man den OpenGL-Modus einschaltet...


----------



## radiac (14. Nov 2009)

Hey ihr 2 . Danke für die Hilfe.


Also das Bild wird als Tilebasierende Map gezeichnet. 400 Tiles insgesamt. Die Map hat keinen Transparenz-wert. Sie ist es auch nicht . Wie gesagt, hab ich das Bild so weit runter geschraub, das es nun ca. 840 kb auf die Wage bringt. Je größer der MB Wert ist, desto schlimmer die FPS.

Okay... jetzt hab ich das mal als Gif konvertiert: Größe beträgt von der gif nun 1.25 Mb. Problem immer noch da. Was komisch ist, ist das als ich früher d3d auf false gesetzt habe hatte ich 280 fps, jetzt nur noch ca. 57. Wenn ich das jetzt auf true setze fast konstant 60. Kann das an dem anderen schrott Rechner gerade nicht testen, aber ich weis, das es, so lange ich nur 60 fps habe dort max 10 sind.
Also "AA" ist ausgeschaltet beim ATI PC. Hab auch empohlene Treiber (Catalyst) installiert... no chance.

Was mich jetzt noch interessierten würde ist die Geschichte mit dem GC... daran ab ich noch garnicht so gedacht. Des es scheint wirklich ein Speicherproblem zu sein... ich hab hier auf meinem Pc 6 Gb Ram und eine 852 MB Grafikkarte...

Meine Freundin Ihr Pc nur 1 GB Ram und eine 256 MB Grafikkarte (Ati x800 AGP).
Zudem ist mir aufgefallen, das wenn ich den Server starte und dann das Spiel, das sich beide die Prozessor Ressourcen zwanghaft teilen. Ist das Spiel aus und nur der SV an, hat der Sv 99 % Prozessor auslastung...

Ja, hab vergessen zu erwähnen, dass das Spiel einen Server hat. Aber der Server hat eigentlich nichts mit den Bildern zu tun... er berechnet nur Position ect...

Also das mit dem GC ist interessant... denn genau das sind die Anzeichen die mir auffallen...
Wenn sie Winamp anhat und ich das SPiel teste ruckelt nach ein paar sekunden (vorher blackscreen) dann die Musik... und dann kommt das Spiel mit 6 FPS...
Die FPS werden im üprigen mit delta errechnet wenn euch das was sagt.

Ich versuche mal das Programm so zu zerflücken, das ich hier ein paar codes reinsetzen kann.
Aber die Geschichte mit dem GC musst du mir näher erläutern .

Bis gleich..


----------



## radiac (14. Nov 2009)

Okay... Problem endlich gefunden. 

Jetzt brauch ich nur noch die Lösung .
Ich habe ein Hudmenü gezeichnet mit Graphics2D. ect....

Die haben die FPS massiv gedrückt. Danke für den Tipp Steev .
Hab das dann mal mit dem OpenGL vesucht... aber ging nicht... heisst das -Dsun.java2d.gl=true???
Jedenfalls, wenn d3d=false ist, habe ich 600 FPS... was seltsam ist, da diese Zahl unrealistisch wirkt .
Aber egal...
Bei meiner freundin werden jetzt 250 FPS angezeigt. Soll mir recht sein .
Aber wenn ich jetzt das Hud zeichnen lassen möchte... wie kann ich das machen, das es die ressourcen nicht verschluckt???

Das Hud wurde sozusagen mit einem Rect gezeichnet... dieses habe ich mit einer Bildtextur versehen und eben auch halb durchsichtig gemacht . Dann ist es natürlich klar.
Muss ich das jetzt weglassen und eine Lite Variante schreiben? Oder kann ich das irgendwie anders lösen?


----------



## radiac (14. Nov 2009)

Steev hat gesagt.:


> Performanceprobleme kann es aber auch schon dann geben, wenn man zu viele Java-Zeichenmethoden verwendet. drawImage geht ja noch relativ schnell, aber die sonstigen draw- und fill-methoden kann man vergessen. Das wird erst schneller wenn man den OpenGL-Modus einschaltet...




Richtig . Das war das Problem... Aber mit Open GL ist das auch nicht zu beheben .
Hab natürlich beim Hud zeichnen extrem in die Javakiste gegriffen... und alles noch mit texturen gefüllt und dann noch halb durchsichtig... und dann noch ca. 60 % dauernd befüllt auf dem Screen 

Das konnte ja nichts werden, wenn Java da probs hat.
Dachte ja eigentlich, das wenn man es zeichnen lässt, weniger perfo-verlusste gibt. Aber...  powned ^_°´


----------



## Steev (14. Nov 2009)

Hmm, dein Quellcode sieht so eigendlich recht ordentlich aus. Auf den ersten Blick kann ich erst einmal keinen Fehler entdecken, der solche Ausmaße haben könnte.
Hast du das Spiel auch schonmal nur im Fenster laufen lassen oder testest du das ganze immer im Vollbildmodus?

Eine andere Frage:
Deine 400 Tiles sind auch wirklich alle 400 unterschiedlich? Oder kann es sein dass du Speicher durch Redundanz verschenkst?

[Java]for(Tile t: tiles)[/Java]
Das ist zwar nur eine Adressgeschichte in dieser for-Konstruktion, ich würde aber an dieser Stelle die klassische Variante verwenden.

[Java]Tile t;
for (int i = 0; i < tiles.size(); i++)[/Java]


Interessant währe vieleicht noch der Code der Klasse "ImageControl", weil die Methode getImageAt ja mehrfach pro Renderung aufgerufen wird.

PS: Da haben wir uns überschnitten...


----------



## Steev (14. Nov 2009)

radiac hat gesagt.:


> Okay... Problem endlich gefunden.
> 
> Jetzt brauch ich nur noch die Lösung .
> Ich habe ein Hudmenü gezeichnet mit Graphics2D. ect....
> ...



Ups, da habe ich doch glatt deinen Post übersehen ;-)
Ich zeichne alle Sachen die sich nicht verändern (Textcaptions, Striche, Rectangles, Background, usw.) in ein BufferdImage und zeichne dann nur noch die Sachen, die sich verändern (FPS-Text, UPS-Text, usw.) mithilfe der java-Zeichenmethoden.

Der Witz dabei ist nämlich, dass es viel schneller ist ein 100x100-Bild zu zeichnen als eine 100 Pixel lange linie. :-D


----------



## radiac (14. Nov 2009)

Hehe, ja... hab mich vorhin gleich mal informiert. Ist wirklich so xD.
Mir wäre es sowieso lieber gewesen die Huds zu zeichnen, doch als ich das Spiel zu Beginn geschrieben habe, hatte ich darauf hin diese FPS Probs.. aber das lag dann noch daran, das ich das d3d aktiv hatte.

Was mich dennoch verwirrt ist, wieso es das langsamer macht anstatt schneller... ? :bahnhof:
Naja, hab mich aber damals schon zufrieden gegeben, solange es gut läuft. .
Nur das mit dem Huds war komisch, denn hab die eigentlich schon über 1 Monat drin gehabt... und ur plötzlich das problem. Ich werde da denke ich mal nur die nötigsten infos mit Strings ausgeben und gut.

Evt. Optional ein Hudmenü... oder so anzeigen lassen . Naja, mal schaun was als nächstes passiert... Ich brauch jetzt keinen Rückschlag mehr .


----------



## radiac (14. Nov 2009)

Okay, noch eine kleine Erkenntnis... hab jetzt noch festgestellt, das GIF-FIles sich besser eignen als PNG Files zumindest für größere Grafiken. Kp ob Gif auch Transparenz unterstützt. Aber echt eine Alternative  PNG = 450 FPS.  GIF = 7xx FPS. 

Wieder ein N1 von mir .


----------



## jason (16. Nov 2009)

Ja, GIF unterstützt Transparenz.

MfG jason


----------

