How to deal with different aspect ratios in libGDX?

时光总嘲笑我的痴心妄想 提交于 2019-11-27 02:41:50

How to do it nowadays:

Since this is one of the most famous questions on libgdx here, I'll give it a little update:

LibGDX v1.0 introduced Viewport to handle this problem. It is a lot easier to use and the scaling strategy is pluggable, which means a single line can change the behaviour and you can play with it and see which one fits your game the best.

Everything you need to know about it can be found here.

Rafay

EDIT: libGDX has evolved. Best answer is now this one by user noone. Be sure to check the link to the Viewport documentation..

As SteveBlack posted the link of the issue that was reported in the stage class, I went there just to discover that the issue (that was not actually my issue) has been resolved in the latest nightlies.

After researching here and there on the internet for the issue I was having, I couldn't find any solutions so decided to contact the person who reported the bug directly. After that, he replied me on libgdx forums and I am indebted to him for his helping me out. Here is the link

It was a single line of code and all you have to do is:

In the resize() methond:

stage.setViewport(640, 480, false);
stage.getCamera().position.set(640/2, 480/2, 0);

Where 640 X 480 is the resolution of your TextureRegion that describes the intended aspect ratio. If your TextureRegion size was 320 X 240, then both the arguments should be changed to the new resolution to do the trick.

Profile link of the original person who actually resolved my issue

Black bars on the left/right or top/bottom look better than just distorting your whole scene to fit the screen. If you target an aspect ratio that's in the middle of the possible ranges (4:3 is probably low end, 16:9 is probably high end), then the bars should stay small for most devices. This also let's you use most of the screen even on bigger screens, and you already have that guy's code so it's pretty easy. It would be even nicer if this was just an option built into libgdx.

But, I think the best approach is to use the whole screen. I haven't done this yet, but it will be the approach I take for my next project. The idea is that if someone has a wider screen, then they should see more on the sides. Chris Pruett talks about how to do this in one of his talks (link to spot in talk--actually, the whole thing is actually pretty good). The idea is to scale for height, and then set your viewport wide enough to fit the screen. OpenGL should take care of displaying the rest. The way he does it is here.

For libgdx, maybe there's an easy way to do this with scene2d by moving the camera over the stage, but I've never actually worked with scene2d. In any case, running the app as a native resizable window is a much easier way to test multiple screen sizes than creating a bunch of AVDs.

See the last part of the Viewport section in the official docs: https://code.google.com/p/libgdx/wiki/scene2d#Viewport

The ResolutionFileResolver class allows you to resolve file names to the best resolution. I believe that will work with different aspect ratios as well, provided you have created sprites for those aspect ratios. There is an example use in the AssetManagerTest.

I'm using that method from http://blog.acamara.es/2012/02/05/keep-screen-aspect-ratio-with-different-resolutions-using-libgdx/

I made this function that returns the point on the screen touched, scaled down to the game position you want.

public Vector2 getScaledPos(float x, float y) {
    float yR = viewport.height / (y - viewport.y);
    y = CAMERA_HEIGHT / yR;

    float xR = viewport.width / (x - viewport.x);
    x = CAMERA_WIDTH / xR;

    return new Vector2(x, CAMERA_HEIGHT - y);
}

Use this in the touchdown / up/ drag and you can check for touch in your game.

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);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!