Search code examples
libgdxtexturesviewportorthographic

Draw texture according to viewport and camera


I don't manage to draw my textures so that they are resized according to the screen resolution.

I am using ScreenViewport (as I want my font to be smooth and without distorsion).

float w = Gdx.graphics.getWidth();                                       
float h = Gdx.graphics.getHeight();   
gameCam = new OrthographicCamera(2f * h/w, 2f);
gamePort = new ScreenViewport(gameCam);

Weirdly, whatever the height and width of the camera the result is the same.

In the resize method, I tried a lot of things :

@Override
public void resize(int width, int height) {
gamePort.update(width, height, true);
renderer.stage.getViewport().update(width, height, true);
gameCam.viewportWidth = width;
gameCam.viewportHeight = height;
gameCam.update();

float aspectRatio = (float) width / (float) height;
gameCam = new OrthographicCamera(2f * aspectRatio, 2f);
gameCam.update();

Finally, in the render method :

public void render() {                                              
    sb.setProjectionMatrix(cam.combined);   
    sb.draw(block.getTexture(), block.getPosition().x, block.getPosition().y, BLOCK_WIDTH, BLOCK_HEIGHT);

BLOCK_WIDTH and BLOCK_HEIGHT = 48 My textures are 512px so I want them to be smaller.

As you can see in the image below, when the device has a big resolution, even when I resize the window, the textures keep the same size and position. I don't have this problem with the table of scores on top of the stage.

enter image description here


Solution

  • A question about resizing sprites was answered here:

    How to resize a sprite in Libgdx?

    So instead of using batch.draw(sprite,...), try sprite.draw(batch) instead.

    I strictly use LibGDX's Stage and Actors as it makes resizing and positioning components (among other things) very easy. When using ScreenViewport I set the size of my components to be some percentage of the screen size. This scales perfectly to different screen sizes.

    For example, instead of hard coding a button to be exactly 100 pixels wide, I set it to be Gdx.graphics.getWidth() * 0.10f and this sets the button width 10% of the screen width regardless of the screen's resolution.

    You can do the same thing with position also. Instead of setting the position to 50 pixels set it to Gdx.graphics.getWidth() * 0.5f and then the x position will be %5 of the screen width.

    If your blocks are going to be aligned in some kind of a grid, then another option for positioning would be to use LibGDX Image instead of Sprite. The Image is based on Actor and it would allow you to put all your blocks into a Table which would automatically re-position itself when resizing the screen. So the blocks would work exactly like the scores at the top of the screen.