I have implemented some screens using libGDX, which will obviously use the Screen class provided by the libGDX framework. However, the implementation of these screens only works with predefined screen sizes. For example, if the sprite was intended for a screen size of 640 x 480 (aspect ratio 4: 3), it will not work as expected on other screen sizes, since sprites correspond to the screen size and do not scale to the screen size at all. Moreover, if simple scaling were provided by libGDX, the problem I ran into would still be there because it would change the aspect ratio of the game screen.
After researching the Internet, I came across a blog / forum that discussed the same issue. I implemented it, and so far it is working fine. But I want to confirm whether this is the best option to achieve this or whether there are better alternatives. Below is the code showing how I deal with this legitimate issue.
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: Recently I found out that libGDX has its own proportions maintenance functions that I would like to discuss here. While searching for aspect ratio questions on the Internet, I came across several forums / developers who had this problem: "How do I keep aspect ratio on different screen sizes?" One of the solutions that really worked for me was posted above.
Later, when I continued implementing the touchDown() methods for the screen, I found that due to scaling when resizing, the coordinates on which I implemented touchDown() would change by a large amount. After working with some code to translate coordinates in accordance with the change in screen size, I reduced this value to a large extent, but I could not maintain them with exact points. For example, if I implemented touchDown() on a texture, changing the screen size would change the touchListener in the texture area by a few pixels left or right, depending on the size, and this was clearly undesirable.
Later I learned that the stage class has its own functionality that supports aspect ratio ( boolean stretch = false ). Now that I have implemented my screen using a scene class, aspect ratio supports it. However, when changing the size or different sizes of the screen, the black area that is generated always appears on the right side of the screen; that is, the screen is not centered, which makes it pretty ugly if the black area is substantially large.
Can any member of the community help me solve this problem?