Wie passt man seine 2D Spiele für andere Auflösungen an ?



  • Hallo, ich wollte schon immer mal 2D-Spiele programmieren. Das funktioniert inzwischen auch gut, allerdings bin ich mit 2D Dingen immer mit einen Problem beschäftigt. Wie macht man es für alle Auflösungen verfügbar ? Wie funktioniert das auf den Android Geräten, da haben andere Geräte ja auch andere Auflösungen. Ich habe jetzt von 2 Dingen gehört:

    1. Eine feste Auflösung z.B. für ein Spiel am Computer mit einer Auflösung von 640x768 .. Dann irgendwie bei höheren Auflösungen kann man das anpassen von der Standart Auflösung "640x786" .. Also das man für eine Auflösung die Dinge annordnet auf den BIldschirm und bei höheren Resolutions dann automatisch dort den Screen angepasst wird

    2. Irgendwie habe ich was von Scaling mit DPI ? oder sowas ??

    Ich hoffe mit kann jemand helfen .. Ich mach sogar in meinen 3D-Spielen inzwischen das Menü in 3D, weil ich nie eine Lösung gefunden habe.



  • zu 1.
    Die Verteilung und Anordnung auf dem Bildschirm macht man skalierfähig, in dem man die Dinge wo sie hin sollen nicht pixelgenau angibt, sondern als Prozentwert.

    D.h. du schreibst nicht:
    Setzte das Icon an der Stelle von 100 pixel in der Y Achse und 50 Pixel in der X Achse, sondern du schreibst:
    Setzte das Icon an der Stelle 10 % von der Y Achse und 5 % in der X Achse.

    Und was die Grafiken betrifft.
    Heutzutage nimmt man skalierfähige Vektorgrafiken, aus diesen erstellt man dann entweder zur Laufzeit die Bitmaps oder man erstellt für jede Auflösung im Vorfeld die Bitmaps passend.
    Letzteres wird auch gemacht, wenn die Grafiken gerendert werden.

    Pixelgenau zeichnen so wie früher, tut die eigentlich niemand mehr, da das zu viel Aufwand wäre, sie in allen Größen zu erstellen.

    Guck dir also mal Programme an, die SVG Grafiken bearbeiten können.
    Bswp Inkscape:
    http://de.wikipedia.org/wiki/Inkscape

    Siehe dazu auch:
    http://de.wikipedia.org/wiki/Scalable_Vector_Graphics

    Alternativ dazu ist wie schon gesagt das Rendern einer 3d Szene in ein 2d Bitmap möglich.



  • Varianten gibt es viele:
    * Man sucht sich eine Auflösung aus "für" die man entwickelt, und auf allen anderen lässt man einfach die Hardware skalieren. Sieht dann halt nie optimal aus, ausser auf genau der Auslösung die man sich ausgesucht hat.
    * Man verwendet eine relativ hohe Auflösung für die ganzen (z.B. gerenderten) Grafiken, und skaliert diese vor Beginn des Spiels auf die benötigte Auflösung runter. Der Vorteil gegenüber dem "live" Skalieren über die GPU (=1. Variante) ist, dass man dabei wesentlich bessere Filter verwenden kann, da es nicht eben nicht "live" sein muss.
    * Man verwendet wie Vektorchef schon geschrieben hat skalierbare Vektorgrafiken und erzeugt dann vor Beginn des Spiels z.B. über einen SVG Renderer die pixelgenauen 2D Grafiken. Wenn man die Art Grafiken die man machen möchte damit hinbekommt, dann ist diese Möglichkeit sicher sehr gut.
    * Man verwendet gleich 3D Objekte die man live als 3D Objekte rendert - auch wenn das Spiel nur 2D ist.

    Der Nachteil der ersten beiden Varianten ist, dass man damit bestimmte Effekte nicht gut machen kann. z.B. kannst du damit keine "superdünne" schwarze Outline um deine Objekte rummachen. Denn entweder ist sie unnötig dick (=auf höherauflösenden Devices deutlich mehr als 1 Pixel), oder sie ist zu dünn (=so dünn dass sie bei niedrigeren Auflösungen schon nirgends mehr ganz schwarz ist).

    Der Nachteil der anderen beiden Varianten ist, dass man dadurch in der Art der Grafiken die man machen kann eingeschränkt wird.

    @Vektorchef
    Kann man mit SVG/... z.B. sowas wie oben erwähnt machen - also dass man definiert dass man eine 1 Pixel dicke schwarze Outline um etwas haben möchte, die aber eben wirklich 1 Pixel dick gemacht wird, und nicht auf hochauflösenden Displays dicker?
    Bzw. etwas ähnliches wie das Grid-Fitting bei Fonts. Also dass man die Dicke der Linie schon ganz normal in Weltkoordinaten angibt, der Renderer aber verhindert dass sie "zu dünn" gemacht wird.

    Wenn nicht, dann ist nämlich der einzig echte Vorteil von SVG oder anderen Vektorformaten, dass man damit Platz spart. Wenn ich nämlich ein normales SVG mit - sagen wir mal - der 3 fachen Auflösung die ich tatsächlich brauche rausrendere, und dann einfach runterskaliere (z.B. mit nem Spline Filter und natürlich Gamma-korrekt), dann kann man das Ergebnis kaum von dem Output unterscheiden den man direkt vom Renderer in der Auflösung bekommen hätte.

    -----

    Ich *vermute* dass man mit der 2. oben erwähnten Möglichkeit recht weit kommen müsste, und das auch ohne all zu viel Speicher zu verbraten (z.B. durch geschicktes "vorfiltern" der 2~3x zu grossen Grafiken - wodurch dann z.B. PNG deutlich besser komprimieren kann).
    Leider fehlt mir die Zeit mich damit - ohne konkreten Anwendungsfall - zu beschäftigen. Und konkreten Anwendungsfall hab ich halt momentan keinen.



  • hustbaer schrieb:

    * Man verwendet eine relativ hohe Auflösung für die ganzen (z.B. gerenderten) Grafiken, und skaliert diese vor Beginn des Spiels auf die benötigte Auflösung runter. Der Vorteil gegenüber dem "live" Skalieren über die GPU (=1. Variante) ist, dass man dabei wesentlich bessere Filter verwenden kann, da es nicht eben nicht "live" sein muss.

    Zu ergänzen sei aber noch, dass es nicht wirklich gut funktioniert, da Details, die man vielleicht haben möchte, durch das runterskalieren verloren gehen.

    Jeder der schon einmal Pixelbasierte Icons kleiner gemacht hat, wird das sicher schonmal gesehen haben. Und wenn dann noch ein Weichzeichner dazukommt, wird es Katastrophal.

    Würde ich also nicht empfehlen, lieber das Zeugs in 3d rendern und dann die einzelnen Grafiken für die jeweiligen Auflösungen erstellen.
    Damit erreicht man alles, auch die Dinge, die sich mit Vektorgrafiken nur schwierig bzw. aufwendig umsetzen lassen.

    @Vektorchef
    Kann man mit SVG/... z.B. sowas wie oben erwähnt machen - also dass man definiert dass man eine 1 Pixel dicke schwarze Outline um etwas haben möchte, die aber eben wirklich 1 Pixel dick gemacht wird, und nicht auf hochauflösenden Displays dicker?

    Naja, man könnte natürlich on the fly berechnen, wieviel Prozent so ein Rahmen breit sein muss, damit er auf der gewählten Auflösung etwa 1 Pixel groß ist.
    Das müsste schon gehen.
    Allerdings muss man aufpassen, dass keine Rahmendetails bei Bereichen verloren gehen, die kleiner als sagen wir mal 0,5 Pixelgröße sind. Insofern müßte man es also erzwingen, das alles was kleiner als 0,5 groß ist, trotzdem auf einen 1 Pixel gerundet wird.



  • Vektorchef schrieb:

    hustbaer schrieb:

    * Man verwendet eine relativ hohe Auflösung für die ganzen (z.B. gerenderten) Grafiken, und skaliert diese vor Beginn des Spiels auf die benötigte Auflösung runter. Der Vorteil gegenüber dem "live" Skalieren über die GPU (=1. Variante) ist, dass man dabei wesentlich bessere Filter verwenden kann, da es nicht eben nicht "live" sein muss.

    Zu ergänzen sei aber noch, dass es nicht wirklich gut funktioniert, da Details, die man vielleicht haben möchte, durch das runterskalieren verloren gehen.

    Jeder der schon einmal Pixelbasierte Icons kleiner gemacht hat, wird das sicher schonmal gesehen haben. Und wenn dann noch ein Weichzeichner dazukommt, wird es Katastrophal.

    Würde ich also nicht empfehlen, lieber das Zeugs in 3d rendern und dann die einzelnen Grafiken für die jeweiligen Auflösungen erstellen.
    Damit erreicht man alles, auch die Dinge, die sich mit Vektorgrafiken nur schwierig bzw. aufwendig umsetzen lassen.

    Verstehe ich nicht.
    Was schlimm ist, ist z.B. mit miesen Filtern (bikubisch oder schlechter) um wenige Prozent runterzuskalieren. Also von 120 auf 100 Pixel oder so.
    Aber wo genau ist der Unterschied zwischen "gleich in 100x100 rausrendern" und "in 300x300 rausrendern und dann 1:3 runterskalieren"?
    Klar, nicht-ganzzahlige Faktoren sind blöd. Fällt aber weit weniger auf wenn man a) immer auf 50% oder kleiner skaliert und b) entsprechend gute Filter verwendet.

    Das Problem mit den fehlenden Details z.B. hat man doch beim Rausrendern in geringerer Auflösung genau so...?

    Was natürlich sicher was bringt, ist, wenn man nicht nur für alle Auflösungen extra rausrendert, sondern auch die Nachberabeitung extra für jede Auslösung anpasst. Bzw. im Extremfall sogar bereits vor dem Rausrendern Anpassungen für die jeweilige Auflösung vornimmt. Was dann aber massiv viel mehr Aufwand ist.

    Naja, man könnte natürlich on the fly berechnen, wieviel Prozent so ein Rahmen breit sein muss, damit er auf der gewählten Auflösung etwa 1 Pixel groß ist.
    Das müsste schon gehen.
    Allerdings muss man aufpassen, dass keine Rahmendetails bei Bereichen verloren gehen, die kleiner als sagen wir mal 0,5 Pixelgröße sind. Insofern müßte man es also erzwingen, das alles was kleiner als 0,5 groß ist, trotzdem auf einen 1 Pixel gerundet wird.

    Dass man das mit Hand machen bzw. sich dafür selbst 'was programmieren kann ist mir auch klar 😉
    Ich meinte eher ob's dafür was fertiges gibt. Weil wenn nicht, dann haben wie gesagt die SVGs vom geringeren Speicherplatzverbrauch abgesehen keine echten Vorteile gegenüber ausreichend grossen Bitmaps die man runterskaliert.



  • hustbaer schrieb:

    Kann man mit SVG/... z.B. sowas wie oben erwähnt machen - also dass man definiert dass man eine 1 Pixel dicke schwarze Outline um etwas haben möchte, die aber eben wirklich 1 Pixel dick gemacht wird, und nicht auf hochauflösenden Displays dicker?

    Die stroke-width kannst Du sowohl anteilig als auch absolut (cm, in, px, em...) angeben.
    http://www.w3.org/TR/SVG11/painting.html#StrokeWidthProperty



  • Vektorchef schrieb:

    zu 1.
    Die Verteilung und Anordnung auf dem Bildschirm macht man skalierfähig, in dem man die Dinge wo sie hin sollen nicht pixelgenau angibt, sondern als Prozentwert.

    D.h. du schreibst nicht:
    Setzte das Icon an der Stelle von 100 pixel in der Y Achse und 50 Pixel in der X Achse, sondern du schreibst:
    Setzte das Icon an der Stelle 10 % von der Y Achse und 5 % in der X Achse.

    Und was die Grafiken betrifft.
    Heutzutage nimmt man skalierfähige Vektorgrafiken, aus diesen erstellt man dann entweder zur Laufzeit die Bitmaps oder man erstellt für jede Auflösung im Vorfeld die Bitmaps passend.
    Letzteres wird auch gemacht, wenn die Grafiken gerendert werden.

    Pixelgenau zeichnen so wie früher, tut die eigentlich niemand mehr, da das zu viel Aufwand wäre, sie in allen Größen zu erstellen.

    Guck dir also mal Programme an, die SVG Grafiken bearbeiten können.
    Bswp Inkscape:
    http://de.wikipedia.org/wiki/Inkscape

    Siehe dazu auch:
    http://de.wikipedia.org/wiki/Scalable_Vector_Graphics

    Alternativ dazu ist wie schon gesagt das Rendern einer 3d Szene in ein 2d Bitmap möglich.

    ganz recht,
    wenn du z.B.: bis jetzt eine Sprite 100*80 bei der Auflösung 1000*800 hattest,
    rechnest du erst (nicht im Skript) 1000/100, 8000/800 , das ergibt dann 10 und 10.
    Dann nimmst du irgendeine auflösung und nimmst dann AuflösungX / 10 und AuflösungY / 10 😃


Log in to reply