Lösungsunabhängigkeit in libGDX


22

Wie mache ich meine libGDX-Spielauflösung / -dichte unabhängig? Gibt es eine Möglichkeit, die Bildgröße unabhängig von der zugrunde liegenden Dichte als "absolut" festzulegen?

Ich mache ein sehr einfaches Kinderspiel. Es werden nur ein paar Sprites auf dem Bildschirm angezeigt und Text für Menüs (hauptsächlich Optionsmenü). Was ich wissen möchte, ist: Wie mache ich die Auflösung meiner Sprites / Schriften unabhängig? (Ich habe sie in meine eigenen Klassen eingepackt, um es einfacher zu machen.)

Da es sich um ein einfaches Kinderspiel handelt, muss ich mir keine Sorgen um den "spielbaren Bereich" des Spiels machen. Ich möchte so viel Platz wie möglich auf dem Bildschirm haben.

Was ich gerade mache, was sehr falsch zu sein scheint, ist, einfach Bilder zu erstellen, die für große Auflösungen geeignet sind, und sie dann zu verkleinern (oder selten zu vergrößern), um sie an die Bildschirmgröße anzupassen. Dies scheint in Ordnung zu sein (in der Desktop-Version), auch mit linearem Mapping auf meinen Texturen, aber die kleineren Auflösungen sehen hässlich aus.

Dies scheint auch angesichts der "geräteunabhängigen Pixel" (DPs) von Android zu fliegen. Oder fehlt mir vielleicht etwas und libGDX kümmert sich schon irgendwie darum?

Wie kann man das am besten angehen? Ich habe diesen Link gefunden. Ist dies eine gute Möglichkeit, das Problem zu lösen ?: http://www.dandeliongamestudio.com/2011/09/12/android-fragmentation-density-independent-pixel-dip/

Es wird erwähnt, wie die Bilder gesteuert werden, es wird jedoch nicht erwähnt, wie die Schrift- / Bildgrößen unabhängig von der Dichte festgelegt werden.



@thedaian nicht ganz. Hier geht es um Auflösung; Ich mache mir mehr Sorgen um das Zusammenspiel von Dichte und Auflösung.
Asche999

Antworten:


12

Da Sie die Gerätedichte lesen und Schriftarten zur Laufzeit in libgdx rendern können, verwende ich diese Lösung, um eine dichteunabhängige Schriftgröße zu erzielen:

float densityIndependentSize = origFontSize * Gdx.graphics.getDensity();
int fontSize = Math.round(densityIndependentSize );
BitmapFont font = generator.generateFont(fontSize );

In meiner Diskussion geht es sowohl um Bilder als auch um Schriftarten. +1 für dynamisches Zeichensatz-Rendering (das mache ich schon).
Asche999

10

Um dies in libgdx zu erreichen, können Sie die "orthographicCamera" verwenden, in der Sie die Größe zuweisen, die Sie verwenden möchten, und in jeder Auflösung können Sie alle Ihre Bilder auf diese Größe skaliert sehen (ich verwende das 800X480, da es der größere Bildschirm in Android ist ) und es funktioniert gut :)

public class GameStage extends Stage 
{ 
     public GameStage(float width, float height, boolean stretch) 
     { 
          this.camera = new OrthographicCamera(800, 480);
          this.camera.position.set(800/2, 480/2, 0f); 
     } 
}

Kann ich bitte ein Codebeispiel bekommen?
Asche999

Das ist der Code, und Sie erstellen eine Klasse, die die Screen-Schnittstelle implementiert, in dem Konstruktor, den Sie für Ihre Bühne erstellen, und in der Render-Methode setzen Sie stage.draw (). Wenn Sie Stages nicht verwenden möchten, können Sie eine Variable in der durch Screen implementierten Klasse vom Typ Camera deklarieren und das Gleiche tun wie in Stage, aber bei der Rendermethode wenden Sie ein Update auf die Kamera an.
Rudy_TM

Das funktioniert eigentlich ganz gut.
you786

4

Ich glaube, dass die "geräteunabhängigen Pixel" von Android nur ein Maßstab für die Klassifizierung von Geräten sind und eigentlich nicht als renderbare Pixel verfügbar sind. Sie verpassen also keine magische DPI-Lösungsinfrastruktur. Soweit ich den Stand der Technik hier verstehe, haben Sie alle Möglichkeiten entdeckt. Es gibt zwei grundlegende Ansätze für den Umgang mit verschiedenen Geräten:

  1. Skalieren Sie vorhandene Bilder so, dass sie mit der tatsächlichen DPI des Geräts übereinstimmen.
  2. Wählen Sie zur Laufzeit basierend auf der DPI aus einer Vielzahl von vorskalierten Bildern.

Natürlich können Sie eine Mischung aus beidem erstellen (ein ungefähr genaues Bild auswählen und dann skalieren) oder unterschiedliche Ansätze für verschiedene Elemente Ihrer Benutzeroberfläche verwenden (z. B. bereits vorhandene Bilder für Schriftarten / Text und dynamische Skalierung für das Gameplay) Sprites).

Was Ihr spezielles Spiel versucht, kann wirklich einen Unterschied darin machen, welcher Ansatz sinnvoller ist. Wenn Sie beispielsweise ein Bildschirmmenü haben, sollten Sie sicherstellen, dass die Schaltflächen ein vernünftiges Vielfaches einer Fingerspitzengröße haben (die Schaltfläche ist also immer leicht zu drücken, aber nicht größer als nötig für große Geräte wie Tablets). Wenn Sie alternativ versuchen, ein Puzzlespiel zu erstellen, bei dem sichergestellt werden soll, dass das gesamte Puzzle auf einmal sichtbar ist, müssen Sie die Elemente so skalieren, dass sie auf den Bildschirm passen (z. B. mit einem Tic-Tac-Toe) Vielleicht möchten Sie, dass jedes Element ungefähr 1/3 des Bildschirms ausmacht.

Ich denke, für Schriftarten mit vielen feinen Details möchten Sie eine Vielzahl von vorgerenderten Bildern mit Text haben und dann die am besten passende auswählen. Tasten können also ihre relative Form / Größe von einem Gerät zum anderen ändern, sehen aber im Allgemeinen immer gut aus.

In Mario Zerchners Beginning Android Games finden Sie eine Diskussion der Probleme und einige Lösungen. Beachten Sie, dass Mario der Autor von libGDX ist, daher spiegelt der Ansatz des Buches den von libGDX wider (beachten Sie, dass es sich nicht um eins zu eins handelt, sondern um das Schreiben einer Bibliothek, die libGDX ähnelt, aber nicht um libGDX selbst).


Selbst wenn ich aus vorgefertigten Bildersammlungen wähle, die auf DPI basieren, sehe ich nicht, wie ich garantieren kann, dass "dieses Sprite als 64x64 angezeigt werden muss".
Asche999

1
Ich bin davon ausgegangen, dass Sie Ihre OpenGL-Kamera so eingestellt haben, dass sie der physischen Anzeige entspricht, also entspricht 1 OpenGL-Pixel 1 Anzeigepixel. Zu diesem Zeitpunkt wird ein 64x64-Bild auf dem Bildschirm als 64x64 angezeigt. Wie Rudy_TM hervorhebt, können Sie mit dem Kamera-Mapping herumspielen, um eine Skalierung des gesamten Bildschirms zu erhalten.
PT

Okay, das sieht aus wie die "geheime Sauce", nach der ich gesucht habe. Ich werde es überprüfen und dich wissen lassen, danke.
Asche999

0

Eine Möglichkeit, dies zu tun, besteht darin, ein minimales Seitenverhältnis und ein maximales Seitenverhältnis für Ihr Spiel zu definieren. Dies sind die Verhältnisse, die Sie unterstützen möchten. Dann müssen Sie ein Ansichtsfenster verwenden, das jetzt in libGdx bereitgestellt wird. Das Ansichtsfenster skaliert Ihre Welt gemäß den von Ihnen angegebenen Einstellungen.

Es gibt verschiedene Arten von Ansichtsfenstern, und Sie müssen das für Ihr Spiel am besten geeignete auswählen.

Sie können beispielsweise ExtendViewport verwenden und entweder Ihre Höhe oder Breite festlegen und die andere berechnen. Dann müssen Sie sicherstellen, dass alle Grafiken in Ihrem minimalen Seitenverhältnis angezeigt werden. Das Ansichtsfenster "Erweitern" skaliert Ihre Grafiken auf das richtige Seitenverhältnis, ohne die Grafiken zu verzerren. Der ExtendViewport fügt Ihrer Welt jedoch zusätzlichen Speicherplatz hinzu. Daher sollten Sie auch Grafiken für Hintergründe bereitstellen, die Ihr gesamtes abgedecktes Seitenverhältnis abdecken. Wenn die Welt kleiner als Ihr maximales Seitenverhältnis ist, wird der zusätzliche Teil der Grafiken dies nicht tun gezeigt werden.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.