Question

I am a newbies in Android and I am learning how to use libgdx as well. I found a few tutorials that use the “DisplayScreen extends AbstractScreen” coding technique, and they use Stage and Actor for displaying output. My interpretation of this coding technique is that DisplayScreen will use whatever in AbstractScreen unless it is @Override (please correct me if I am wrong).

Therefore, if I place the code in AbstractScreen resize() to scale the display to a bigger screen yet maintaining the aspect ratio; the stage in DisplayScreen should resize it to fit the bigger screen. The main objective is that I only want to concentrate my game development in 800x480 environment and completely ignore all different sizes/resolution. The resize() in AbstractScreen will do all the hard work to scale and fit my game to any resolution.

Please allow me to use my test example for better explanation. I have no problem displaying my 800x480 black background on my phone. However, the same background was displayed BUT not maintaining its aspect ratio on Nexus 7.

This turorial fixed my problem mentioned above (I adopted to have two black bars on both side of the screen). However, I have a small problem integrating this solution to the “DisplayScreen extends AbstractScreen” technique.

Please see this screen shot here. My issues are:

  1. Why my black box is not resize to fit the screen, yet leaving two red bar on both sides of the screen?
  2. I don’t understand why the black image only displaying 766x480 on my Nexus 7?

It will be fantastic if someone can point me to the right direction.

Code for awesomegame

package com.example.somegame;

import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.assets.AssetManager;
import com.example.somegame.screens.DisplayScreen;

public class awesomegame extends Game {

public static AssetManager AssetManager = new AssetManager();

@Override
public void create() {
}

@Override
public void render() {
    super.render();
}

@Override
public void resize(int width, int height) {
    super.resize(width, height);
    setScreen( new DisplayScreen(this) );

}

@Override
public void setScreen(Screen screen) {
    super.setScreen( screen );
}

Code for AbstractScreen

package com.example.somegame.screens;

import com.example.somegame.awesomegame;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.utils.Scaling;

public class AbstractScreen implements Screen{

private awesomegame awesomegame;
private Stage stage;

private BitmapFont font;
    private SpriteBatch batch;
private OrthographicCamera camera;

public AbstractScreen(awesomegame awesomegame) {
    this.awesomegame = awesomegame;

    camera = new OrthographicCamera();
    camera.setToOrtho(false, 800, 480);
    camera.update();

    stage = new Stage(800, 480, false);
}

@Override
public void render(float delta) {
    stage.act( delta );
    Gdx.gl.glClearColor( .5f, .5f, 0f, 1f );
    Gdx.gl.glClear( GL20.GL_COLOR_BUFFER_BIT );

    stage.draw();
}

@Override
public void resize(int width, int height) {
    Vector2 size = Scaling.fit.apply(800, 480, width, height);
    int viewportX = (int)(width - size.x) / 2;
    int viewportY = (int)(height - size.y) / 2;
    int viewportWidth = (int)size.x;
    int viewportHeight = (int)size.y;
    Gdx.gl.glViewport(viewportX, viewportY, viewportWidth, viewportHeight);
    stage.setViewport(800, 480, true);
}

Code for DisplayScreen

package com.example.somegame.screens;

import com.example.somegame.awesomegame;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Image;

public class DisplayScreen extends AbstractScreen {

private Image loadingBg;

private Stage stage;

float loadingPercent;

public DisplayScreen(awesomegame awesomegame) {
    super (awesomegame);
}

@Override
public void show()
{
    super.show();

    awesomegame.AssetManager.load("img/loading.atlas", TextureAtlas.class);
    awesomegame.AssetManager.finishLoading();

    stage = new Stage();

    TextureAtlas atlas = awesomegame.AssetManager.get("img/loading.atlas", TextureAtlas.class);


    loadingBg = new Image(atlas.findRegion("loadingBg"));

    loadingBg.setSize(800, 480);
    loadingBg.setX(0);
    loadingBg.setY(0);

    stage.addActor(loadingBg);

    // add all asset need to be loaded here. for example
    // awesomegame.AssetManager.load("img/whatever.pack", TextureAtlas.class);

}

@Override
public void render(float delta) {
    Gdx.gl.glClearColor( 1f, 0f, 0f, 1f );
    stage.draw();

}
Was it helpful?

Solution

The Nexus 7 has a screen resolution of 1280 x 800, but part of the height is used for the onscreen menu panel (with the back/home/menu buttons).

The main culprit in your code is here, where you try to enforce a specific aspect ratio that doesn't fit this adjusted dimension, resulting in those bars on the side:

public void resize(int width, int height) {
    Vector2 size = Scaling.fit.apply(800, 480, width, height);
    ...
}

Looks like you pulled that resize function off another stackoverflow post. I had done the same, but switched to something simpler when i ran into the same issue:

public void resize(int width, int height) {
    stage.setViewport(true, width,height);
    stage.getCamera().setToOrtho(false,width,height);
    ...
}

OTHER TIPS

This code works for me with the latest update:

OrthographicCamera is cam, this makes no cropping, just changes the viewport so the width is still "that many" times larger than the actual window/device

public void resize(int width, int height) {
    int newW = width, newH = height;
    if (cam.viewportWidth > width) {
        float scale = (float) cam.viewportWidth / (float) width;
        newW *= scale;
        newH *= scale;
    }

    // true here to flip the Y-axis
    cam.setToOrtho(true, newW, newH);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top