# 2D Spiel im Vollbild langsamer als im Fenster



## scari (1. Apr 2012)

Hallo!

ich habe mir von Quaxli dieses Tuorial angeguckt und ein kleines 2D Spiel programmiert.
http://www.java-forum.org/spiele-multimedia-programmierung/54795-quaxli-2d-spiele-tutorial.html

Ich nutze dort ein JPanel und zeichne darauf mit der Methode paintComponent. Habe dort auch eine run() Methode implementiert um mein Panel alle 10ms neuzuzeichnen(repaint). Es funktioniert im Fenstermodus alles wunderbar, ohne irgendwelche Ruckler usw. Sobald ich aber mit diesem Code


```
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice device;

        device = ge.getDefaultScreenDevice();
        if(device.isFullScreenSupported())
        {
            device.setFullScreenWindow(this);
            device.setDisplayMode(new DisplayMode( 1280, 1024 , 32, 60));
        }
```

in den Fullscreenmode wechsel, ist alles langsamer und träge. Die Bewegungen sind nicht mehr flüssig.
Woran kann das liegen? Ich hab jetzt bewusst darauf verzichtet meinen Code zu posten, da es zu viel wäre.
Viele Dank schon mal.


----------



## jule37 (2. Apr 2012)

gib mal die fps auf dem bildschirm aus. gibt es einen unterschied zwischen fenster und vollbild?

allgemein habe ich mit java2d, was performance betrifft, schlechte erfahrungen gemacht. du solltest dir vielleicht lieber mal opengl anschauen. noch besser: gleich eine game engine, wie z.B. jmonkey, benutzen.


----------



## scari (2. Apr 2012)

Die FPS bleibt komischerweise gleich, obwohl da alles langsamer ist. Eine fertige Game Engine darf ich leider nicht benutzen, da das ein Projekt für die Schule ist. Kann es sein, dass es etwas mit der repaint() Methode zu tun haben könnte? Habe desöfteren im Netz was von Active Rendering gehört, wo man diese Methode vermeidet. Aber im Fenster läuft ja alles super :bahnhof:


----------



## jule37 (2. Apr 2012)

wenn die fps exakt gleich sind sollte eigtl. alles in ordnung sein.

der nächste schritt, den ich jetzt tun würde ist profilen. d.h. alle möglichen vorgänge messen. wie lange dauert update, wie lange draw, etc - gibt es unterschiede zwischen windowed und fullscreen? es kann auch helfen mal im debugmodus durchzusteppen. zumindest gibt es keinen weg daran vorbei den gesamten prozess bis ins kleinste detail zu verstehen, dann findet man den fehler irgendwann garantiert.

du könntest zusätzlich mal deinen game loop posten mit update und draw, dann schaue ich mal ob mir was auffällt.

allgemeine probleme mit java2d im fullscreen exclusive sind mir nicht bekannt. grundsätzlich muss das gehen, also ist höchst wahrscheinlich bei dir im code ein fehler.


----------



## Fu3L (2. Apr 2012)

Es könnte doch sein, dass du sagst, sagen wir ein Ball, sei 10 px pro Sekunde unterwegs. 
Wenn dein Fenster normal 500x500 groß ist, legt der Ball in 50 Sekunden seinen Weg über das Spielfeld zurück, bei Vollbild mit 1920xwattweißich pixeln braucht er halt annähernd 200 Sekunden.

Obwohl ich das in meinem BreakoutKlon abfange, empfinde ich es aber auch auf einem riesen Bildschirm etwas ruckelnd... Kann sein, dass dann nich oft genug neu gezeichnet wird oder irgendwas Psychologisches^^


----------



## scari (2. Apr 2012)

Fu3L hat gesagt.:


> Es könnte doch sein, dass du sagst, sagen wir ein Ball, sei 10 px pro Sekunde unterwegs.
> Wenn dein Fenster normal 500x500 groß ist, legt der Ball in 50 Sekunden seinen Weg über das Spielfeld zurück, bei Vollbild mit 1920xwattweißich pixeln braucht er halt annähernd 200 Sekunden.
> 
> Obwohl ich das in meinem BreakoutKlon abfange, empfinde ich es aber auch auf einem riesen Bildschirm etwas ruckelnd... Kann sein, dass dann nich oft genug neu gezeichnet wird oder irgendwas Psychologisches^^



Ne daran liegt das nicht, habe das Fenster vorübergehend auf den ganzen Bildschirm skaliert. Der Unterschied ist schon deutlich.



jule37 hat gesagt.:


> wenn die fps exakt gleich sind sollte eigtl. alles in ordnung sein.
> 
> der nächste schritt, den ich jetzt tun würde ist profilen. d.h. alle möglichen vorgänge messen. wie lange dauert update, wie lange draw, etc - gibt es unterschiede zwischen windowed und fullscreen? es kann auch helfen mal im debugmodus durchzusteppen. zumindest gibt es keinen weg daran vorbei den gesamten prozess bis ins kleinste detail zu verstehen, dann findet man den fehler irgendwann garantiert.
> 
> ...



Danke für den Tipp. Ich habe mal ein neues leeres Projekt mit dem Grundgerüst(gameloop, draw) von meinem Spiel als Basis genommen und dann in den Vollbildmodus gewechselt. Selbst die Maus hat da etwas geruckelt. Jedenfalls liegts diesem Konstrukt hier:


```
@Override
    public void run() 
    {
        while(this.isVisible())
        {

                delta = System.nanoTime() - last;
                last = System.nanoTime();
                fps = ((long) 1e9)/delta;

                if (isRight)
                {
                    x+= velocity * (delta/1e9);
                    System.out.println(x);
                }
            
            repaint();
            
            try
            {
                Thread.sleep(10);
            }
            catch(Exception ex)
            {

            }
       }
    }
```

Und zwar die While Schleife ist das Probelm. Lasse ich sie weg, ruckelt da nichts mehr. Nur wie kann ich das jetzt umschreiben? :bahnhof: Ich brauch ja unbedingt eine Schleife um alles zu aktualisieren.
Die run Methode ist in meinem JPanel. Dieser wird dann in einem neuen Thread gestartet.


----------



## andre111 (5. Apr 2012)

Naja, das repaint zeichnet nicht direkt sondern veranlasst soweit ich weis nur das Fenster in nächster Zeit gerendert zu werden. Wenn zu viele repaints schnell hintereinander kommen werden ein paar ignoriert/"zusammengefasst", wenn ich mich nicht irre. Dementsprechend sind die berechneten FPS zwar gleich, aber wie oft wirklich gezeichnet wird könnte sich zwischen Vollbild und Fenster Modus durchaus unterscheiden


----------



## scari (6. Apr 2012)

andre111 hat gesagt.:


> Naja, das repaint zeichnet nicht direkt sondern veranlasst soweit ich weis nur das Fenster in nächster Zeit gerendert zu werden. Wenn zu viele repaints schnell hintereinander kommen werden ein paar ignoriert/"zusammengefasst", wenn ich mich nicht irre. Dementsprechend sind die berechneten FPS zwar gleich, aber wie oft wirklich gezeichnet wird könnte sich zwischen Vollbild und Fenster Modus durchaus unterscheiden



OK danke für die Info. Wie kann ich denn eine Methode schreiben(statt repaint), die das Panel immer veranlasst, alle 10ms zu zeichnen?


----------



## jule37 (7. Apr 2012)

folgendes problem: deine sleep-zeit ist konstant 10 milliesekunden. dadurch schläft der thread nach jedem frame 10ms, selbst wenn er dafür keine zeit hat, weil das zeichnen zu lange dauert. versuche die sleep zeit so zu berechnen, dass sie der gewünschten framerate entspricht. wenn der frame zu lange gebraucht hat, dann kein sleep, sonst wirfst du wertvolle zeit zum fenster raus 

ansonsten findest du hier ausführliche allgemeine informationen
Lesson: Full-Screen Exclusive Mode API (The Java™ Tutorials > Bonus)

noch ein hinweis: fps = 1 / renderzeit pro frame (in sekunden)


----------



## andre111 (7. Apr 2012)

Das Zeichnen passiert aber nicht in dem Thread, in dem scari repaint() aufruft, da das repaint() nicht sofort neu zeichnet sondern nur in die AWT/Swing-EventQueue ein Event einreiht, das das Neuzeichnen "in näherer" Zukunft auslöst. Dazu sollte die Dokumentation für aktives und passives Rendering weiterhelfen: Passive vs. Active Rendering (The Java™ Tutorials > Bonus > Full-Screen Exclusive Mode API)
So auch laut Byte-Welt-Wiki:


> Der Aufruf der repaint Methode veranlasst indirekt den Aufruf der paintComponent Methode der angesprochenen Komponente, und zwar zu dem für das System am geeignetsten Zeitpunkt.


----------



## scari (10. Apr 2012)

andre111 hat gesagt.:


> Das Zeichnen passiert aber nicht in dem Thread, in dem scari repaint() aufruft, da das repaint() nicht sofort neu zeichnet sondern nur in die AWT/Swing-EventQueue ein Event einreiht, das das Neuzeichnen "in näherer" Zukunft auslöst. Dazu sollte die Dokumentation für aktives und passives Rendering weiterhelfen: Passive vs. Active Rendering (The Java™ Tutorials > Bonus > Full-Screen Exclusive Mode API)
> So auch laut Byte-Welt-Wiki:



danke für den Link. Den Artikel versteh ich jedoch nicht ganz. Ich hab mal wie im Beispiel eine eigene Methode zum Rendern gemacht, die ich dann in der paintComponent aufrufe. Dabei verzichte auch noch auf das repaint(). Jetzt habe ich aber durch das while eine Endlossschleife und das Spiel läuft gar nicht mehr. Kann mir jemand vielleicht ein Beispiel posten? Danke.


----------



## andre111 (10. Apr 2012)

Space Invaders 101 - An Accelerated Java 2D Tutorial fand ich auch immer ganz praktisch.


----------

