He implementado algunas pantallas usando libGDX que obviamente usarían la Screen
clase proporcionada por el marco libGDX. Sin embargo, la implementación de estas pantallas solo funciona con tamaños de pantalla predefinidos. Por ejemplo, si el sprite estaba destinado a una pantalla de tamaño 640 x 480 (relación de aspecto 4: 3), no funcionará como se esperaba en otros tamaños de pantalla porque los sprites se ajustan a los límites de la pantalla y no se ajustan al tamaño de la pantalla. en absoluto. Además, si libGDX hubiera proporcionado un escalado simple, el problema al que me enfrento aún habría estado ahí porque eso haría que la relación de aspecto de la pantalla del juego cambiara.
Después de investigar en Internet, me encontré con un blog / foro que había discutido el mismo tema. Lo he implementado y hasta ahora está funcionando bien. Pero quiero confirmar si esta es la mejor opción para lograrlo o si existen mejores alternativas. A continuación se muestra el código para mostrar cómo estoy lidiando con este problema legítimo.
ENLACE DEL FORO: 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);
}
}
}
ACTUALIZACIÓN: Hace poco me enteré de que libGDX tiene algunas de sus propias funciones para mantener relaciones de aspecto que me gustaría discutir aquí. Mientras buscaba el problema de la relación de aspecto en Internet, encontré varios foros / desarrolladores que tenían este problema de "¿Cómo mantener la relación de aspecto en diferentes tamaños de pantalla?" Una de las soluciones que realmente funcionó para mí se publicó arriba.
Más tarde, cuando procedí a implementar los touchDown()
métodos para la pantalla, descubrí que debido a la escala al cambiar el tamaño, las coordenadas en las que había implementado touchDown()
cambiarían en gran medida. Después de trabajar con un código para traducir las coordenadas de acuerdo con el cambio de tamaño de la pantalla, reduje esta cantidad en gran medida, pero no pude mantenerlas con una precisión milimétrica. Por ejemplo, si lo hubiera implementado touchDown()
en una textura, cambiar el tamaño de la pantalla desplazaría el touchListener en la región de la textura algunos píxeles hacia la derecha o hacia la izquierda, dependiendo del cambio de tamaño y esto obviamente no era deseado.
Más tarde supe que la clase de escenario tiene su propia funcionalidad nativa para mantener la relación de aspecto ( boolean stretch = false
). Ahora que he implementado mi pantalla usando la clase de escenario, la relación de aspecto se mantiene bien. Sin embargo, al cambiar el tamaño o diferentes tamaños de pantalla, el área negra que se genera siempre aparece en el lado derecho de la pantalla; es decir, la pantalla no está centrada, lo que lo hace bastante feo si el área negra es sustancialmente grande.
¿Algún miembro de la comunidad puede ayudarme a resolver este problema?