ceran
ceran

Reputation: 1412

libGDX: size of object in FitViewport is distorted

My goal is to create a game that is always displayed with an aspect ratio of 9:16 (basically 16:9, but upright) using FitViewport; it should be independet of a target device's resolution. In order to test this setup, I created the following minimal working example. A small green square indicates the origin of the coordinate system:

MyGame.java

public class MyGame extends ApplicationAdapter {

    final int WORLD_WIDTH = 900;
    final int WORLD_HEIGHT = 1600;
    Stage stage;
    Viewport vp;        

    public void create() {
        stage = new Stage();
        vp = new FitViewport(WORLD_WIDTH, WORLD_HEIGHT, stage.getCamera());
        stage.setViewport(vp);
        stage.addActor(new MySquare());
    }

    public void render() {
        stage.act();
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        stage.draw();
    }

    public void resize(int width, int height) {
        stage.getViewport().update(width, height, true);
    }

    // dispose...
}

MySquare.java

public class MySquare extends Actor {
    ShapeRenderer renderer = new ShapeRenderer();
    @Override
    public void draw(Batch batch, float alpha){
        batch.end();
        renderer.begin(ShapeRenderer.ShapeType.Filled);
        renderer.setColor(Color.GREEN);
        renderer.rect(0, 0, 50, 50);
        renderer.end();
        batch.begin();
    }
}

Unfortunately, the result is not as expected: As you can see, the green square is actually not a square. This behavior is the same for both Windows and Android (in landscape mode):

enter image description here

However, when setting the size of the window programmatically and explicitly via LwjglApplicationConfiguration in DesktopLauncher.java to a valid 9:16 resolution, the green square is displayed correctly. Why is that and how can I avoid this workaround (which does not work for Android anyway)?

Upvotes: 0

Views: 221

Answers (1)

Tenfour04
Tenfour04

Reputation: 93581

Your problem is that your shape renderer is ignoring the camera. Update it like this:

public void draw(Batch batch, float alpha){
    batch.end();
    renderer.setProjectionMatrix(batch.getProjectionMatrix()); // <<<<< Add this
    renderer.begin(ShapeRenderer.ShapeType.Filled);
    renderer.setColor(Color.GREEN);
    renderer.rect(0, 0, 50, 50);
    renderer.end();
    batch.begin();
}

If you are planning to eventually use sprites, and you're simply wanting rectangle placeholders for your actors, you don't need a custom actor for this. You can use a generic Actor and call setDebug(true) on it, and Stage will automatically draw its outline using an internal ShapeRenderer. Of course, you must first set a size and position on the Actor.

Upvotes: 2

Related Questions