Ich habe einige Bildschirme mit libGDX implementiert, die offensichtlich die Screen
vom libGDX-Framework bereitgestellte Klasse verwenden würden . Die Implementierung für diese Bildschirme funktioniert jedoch nur mit vordefinierten Bildschirmgrößen. Wenn das Sprite beispielsweise für einen Bildschirm mit einer Größe von 640 x 480 (Seitenverhältnis 4: 3) gedacht war, funktioniert es bei anderen Bildschirmgrößen nicht wie vorgesehen, da die Sprites entlang der Bildschirmgrenzen verlaufen und nicht auf die Bildschirmgröße skaliert sind überhaupt. Wenn die libGDX eine einfache Skalierung bereitgestellt hätte, wäre das Problem, mit dem ich konfrontiert bin, immer noch vorhanden, da sich dadurch das Seitenverhältnis des Spielbildschirms ändern würde.
Nachdem ich im Internet recherchiert hatte, stieß ich auf einen Blog / ein Forum , in dem das gleiche Thema diskutiert wurde. Ich habe es implementiert und bis jetzt funktioniert es gut. Ich möchte jedoch bestätigen, ob dies die beste Option ist, um dies zu erreichen, oder ob es bessere Alternativen gibt. Unten finden Sie den Code, der zeigt, wie ich mit diesem legitimen Problem umgehe.
FORUM-LINK: http://www.java-gaming.org/index.php?topic=25685.new
public class SplashScreen implements Screen {
// Aspect Ratio maintenance
private static final int VIRTUAL_WIDTH = 640;
private static final int VIRTUAL_HEIGHT = 480;
private static final float ASPECT_RATIO = (float) VIRTUAL_WIDTH / (float) VIRTUAL_HEIGHT;
private Camera camera;
private Rectangle viewport;
// ------end------
MainGame TempMainGame;
public Texture splashScreen;
public TextureRegion splashScreenRegion;
public SpriteBatch splashScreenSprite;
public SplashScreen(MainGame maingame) {
TempMainGame = maingame;
}
@Override
public void dispose() {
splashScreenSprite.dispose();
splashScreen.dispose();
}
@Override
public void render(float arg0) {
//----Aspect Ratio maintenance
// update camera
camera.update();
camera.apply(Gdx.gl10);
// set viewport
Gdx.gl.glViewport((int) viewport.x, (int) viewport.y,
(int) viewport.width, (int) viewport.height);
// clear previous frame
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
// DRAW EVERYTHING
//--maintenance end--
splashScreenSprite.begin();
splashScreenSprite.disableBlending();
splashScreenSprite.draw(splashScreenRegion, 0, 0);
splashScreenSprite.end();
}
@Override
public void resize(int width, int height) {
//--Aspect Ratio Maintenance--
// calculate new viewport
float aspectRatio = (float)width/(float)height;
float scale = 1f;
Vector2 crop = new Vector2(0f, 0f);
if(aspectRatio > ASPECT_RATIO) {
scale = (float) height / (float) VIRTUAL_HEIGHT;
crop.x = (width - VIRTUAL_WIDTH * scale) / 2f;
} else if(aspectRatio < ASPECT_RATIO) {
scale = (float) width / (float) VIRTUAL_WIDTH;
crop.y = (height - VIRTUAL_HEIGHT * scale) / 2f;
} else {
scale = (float) width / (float) VIRTUAL_WIDTH;
}
float w = (float) VIRTUAL_WIDTH * scale;
float h = (float) VIRTUAL_HEIGHT * scale;
viewport = new Rectangle(crop.x, crop.y, w, h);
//Maintenance ends here--
}
@Override
public void show() {
camera = new OrthographicCamera(VIRTUAL_WIDTH, VIRTUAL_HEIGHT); //Aspect Ratio Maintenance
splashScreen = new Texture(Gdx.files.internal("images/splashScreen.png"));
splashScreenRegion = new TextureRegion(splashScreen, 0, 0, 640, 480);
splashScreenSprite = new SpriteBatch();
if(Assets.load()) {
this.dispose();
TempMainGame.setScreen(TempMainGame.mainmenu);
}
}
}
UPDATE: Ich habe kürzlich erfahren, dass libGDX einige seiner eigenen Funktionen zur Aufrechterhaltung von Seitenverhältnissen hat, die ich hier diskutieren möchte. Bei der Suche nach dem Problem mit dem Seitenverhältnis im Internet bin ich auf mehrere Foren / Entwickler gestoßen, bei denen das Problem aufgetreten ist: "Wie kann das Seitenverhältnis auf verschiedenen Bildschirmgrößen beibehalten werden?" Eine der Lösungen, die wirklich für mich funktioniert haben, wurde oben veröffentlicht.
Als ich später mit der Implementierung der touchDown()
Methoden für den Bildschirm fortfuhr , stellte ich fest, dass sich die von mir implementierten Koordinaten aufgrund der Skalierung beim Ändern der Größe erheblich ändern touchDown()
würden. Nachdem ich mit einem Code gearbeitet hatte, um die Koordinaten gemäß der Bildschirmgröße zu übersetzen, reduzierte ich diesen Betrag erheblich, aber es gelang mir nicht, sie punktgenau zu pflegen. Wenn ich beispielsweise touchDown()
eine Textur implementiert hätte, würde eine Größenänderung des Bildschirms den touchListener im Texturbereich je nach Größenänderung um einige Pixel nach rechts oder links verschieben, was offensichtlich unerwünscht war.
Später erfuhr ich, dass die Stage-Klasse über eine eigene native Funktionalität verfügt, um das Seitenverhältnis beizubehalten ( boolean stretch = false
). Nachdem ich meinen Bildschirm mithilfe der Stage-Klasse implementiert habe, wird das Seitenverhältnis dadurch gut beibehalten. Bei Größenänderung oder unterschiedlichen Bildschirmgrößen wird der erzeugte schwarze Bereich jedoch immer auf der rechten Seite des Bildschirms angezeigt. Das heißt, der Bildschirm ist nicht zentriert, was es ziemlich hässlich macht, wenn der schwarze Bereich wesentlich groß ist.
Kann mir ein Community-Mitglied helfen, dieses Problem zu lösen?
quelle
Antworten:
Wie es heutzutage geht:
Da dies hier eine der bekanntesten Fragen zu libgdx ist, werde ich ein kleines Update geben :
LibGDX v1.0 wurde eingeführt
Viewport
, um dieses Problem zu beheben. Es ist viel einfacher zu bedienen und die Skalierungsstrategie ist steckbar, was bedeutet, dass eine einzelne Zeile das Verhalten ändern kann und Sie damit spielen und sehen können, welche am besten zu Ihrem Spiel passt.Alles, was Sie darüber wissen müssen, finden Sie hier .
quelle
TextureRegion
Streches. Wenn Sie diereszie(int width, int height)
Funktion leer lassen. Das strektTextureRegion
nicht.EDIT: libGDX hat sich weiterentwickelt. Die beste Antwort ist jetzt diese von niemandem. Überprüfen Sie unbedingt den Link zur
Viewport
Dokumentation. .Als SteveBlack den Link zu dem Problem veröffentlichte, das in der Bühnenklasse gemeldet wurde, ging ich dorthin, um festzustellen, dass das Problem (das eigentlich nicht mein Problem war) in den letzten Nightlies behoben wurde.
Nachdem ich hier und da im Internet nach dem Problem gesucht hatte, das ich hatte, konnte ich keine Lösung finden. Deshalb entschied ich mich, die Person zu kontaktieren, die den Fehler direkt gemeldet hatte. Danach antwortete er mir in libgdx-Foren und ich bin ihm zu Dank verpflichtet, dass er mir geholfen hat. Hier ist der Link
Es war eine einzelne Codezeile und alles, was Sie tun müssen, ist:
In der Methode resize ():
Wobei 640 x 480 die Auflösung Ihrer TextureRegion ist, die das beabsichtigte Seitenverhältnis beschreibt. Wenn Ihre TextureRegion-Größe 320 x 240 war, sollten beide Argumente in die neue Auflösung geändert werden, um den Trick auszuführen.
Profillink der ursprünglichen Person, die mein Problem tatsächlich gelöst hat
quelle
setViewport
mit 3 Parametern ist jetzt nicht verfügbar!Schwarze Balken links / rechts oder oben / unten sehen besser aus, als nur die gesamte Szene zu verzerren, um sie an den Bildschirm anzupassen. Wenn Sie ein Seitenverhältnis anstreben, das in der Mitte des möglichen Bereichs liegt (4: 3 ist wahrscheinlich ein niedriges Ende, 16: 9 ist wahrscheinlich ein hohes Ende), sollten die Balken für die meisten Geräte klein bleiben. Auf diese Weise können Sie den größten Teil des Bildschirms auch auf größeren Bildschirmen verwenden, und Sie haben bereits den Code dieses Typen, sodass es ziemlich einfach ist. Es wäre noch schöner, wenn dies nur eine in libgdx integrierte Option wäre.
Ich denke jedoch, dass der beste Ansatz darin besteht, den gesamten Bildschirm zu verwenden. Ich habe das noch nicht getan, aber es wird der Ansatz sein, den ich für mein nächstes Projekt verfolge. Die Idee ist, dass jemand, der einen breiteren Bildschirm hat, mehr an den Seiten sehen sollte. Chris Pruett spricht in einem seiner Vorträge darüber, wie man das macht ( Link zum Spot im Gespräch - eigentlich ist das Ganze eigentlich ziemlich gut). Die Idee ist, die Höhe zu skalieren und dann das Ansichtsfenster so weit einzustellen, dass es auf den Bildschirm passt. OpenGL sollte sich um die Anzeige des Restes kümmern. So wie er es macht, ist hier .
Für libgdx gibt es vielleicht eine einfache Möglichkeit, dies mit scene2d zu tun, indem Sie die Kamera über die Bühne bewegen, aber ich habe noch nie mit scene2d gearbeitet. In jedem Fall ist das Ausführen der App als natives Fenster mit veränderbarer Größe eine viel einfachere Möglichkeit, mehrere Bildschirmgrößen zu testen, als eine Reihe von AVDs zu erstellen.
quelle
Weitere Informationen finden Sie im letzten Teil des Viewport-Abschnitts in den offiziellen Dokumenten: https://code.google.com/p/libgdx/wiki/scene2d#Viewport
quelle
Mit der ResolutionFileResolver- Klasse können Sie Dateinamen in der besten Auflösung auflösen. Ich glaube, dass dies auch mit verschiedenen Seitenverhältnissen funktioniert, vorausgesetzt, Sie haben Sprites für diese Seitenverhältnisse erstellt. Es gibt ein Beispiel für die Verwendung im AssetManagerTest .
quelle
Ich verwende diese Methode von http://blog.acamara.es/2012/02/05/keep-screen-aspect-ratio-with-different-resolutions-using-libgdx/
Ich habe diese Funktion erstellt, die den berührten Punkt auf dem Bildschirm zurückgibt und auf die gewünschte Spielposition verkleinert.
Verwenden Sie dies beim Aufsetzen / Hoch / Ziehen und Sie können in Ihrem Spiel nach Berührungen suchen.
quelle
Dieser Code funktioniert für mich mit dem neuesten Update: * OrthographicCamera ist eine Kamera, dies macht kein Zuschneiden, ändert nur das Ansichtsfenster, sodass die Breite immer noch "so oft" größer ist als das tatsächliche Fenster / Gerät
quelle