在libGDX中如何处理不同的纵横比? [英] How to deal with different aspect ratios in libGDX?

查看:26
本文介绍了在libGDX中如何处理不同的纵横比?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用 libGDX 实现了一些屏幕,这些屏幕显然会使用 libGDX 框架提供的 Screen 类.但是,这些屏幕的实现仅适用于预定义的屏幕尺寸.例如,如果精灵适用于 640 x 480 尺寸的屏幕(4:3 纵横比),它将无法在其他屏幕尺寸上按预期工作,因为精灵符合屏幕边界并且不会缩放到屏幕尺寸根本.此外,如果 libGDX 提供了简单的缩放,我面临的问题仍然存在,因为这会导致游戏屏幕的纵横比发生变化.

I have implemented some screens using libGDX that would obviously use the Screen class provided by the libGDX framework. However, the implementation for these screens works only with pre-defined screen sizes. For example, if the sprite was meant for a 640 x 480 size screen (4:3 Aspect ratio), it won't work as intended on other screen sizes because the sprites go par the screen boundaries and are not scaled to the screen size at all. Moreover, if simple scaling would have been provided by the libGDX, the issue I am facing would have still been there because that would cause the aspect ratio of the game screen to change.

在互联网上进行研究后,我发现了一个博客/论坛 讨论过同样的问题.我已经实现了它,到目前为止它运行良好.但我想确认这是否是实现这一目标的最佳选择,或者是否有更好的替代方案.下面是显示我如何处理这个合法问题的代码.

After researching on internet, I came across a blog/forum that had discussed the same issue. I have 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 to show how I am dealing with this legitimate problem.

论坛链接: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);
        }
    }
}

更新: 我最近了解到 libGDX 有一些自己的功能来保持纵横比,我想在这里讨论一下.在网上搜索宽高比问题时,我遇到了几个论坛/开发者,他们遇到了如何在不同屏幕尺寸上保持宽高比?"的问题.上面发布了对我真正有用的解决方案之一.

UPDATE: I recently came to know that libGDX has some of its own functionality to maintain aspect ratios which I would like to discuss here. While searching the aspect ratio issue across the internet, I came across several forums/developers who had this problem of "How to maintain the aspect ratio on different screen sizes?" One of the solutions that really worked for me was posted above.

后来,当我继续为屏幕实现 touchDown() 方法时,我发现由于缩放调整大小,我在其上实现了 touchDown() 的坐标 会发生很大的变化.在使用一些代码根据屏幕调整大小转换坐标后,我在很大程度上减少了这个数量,但我没有成功地保持它们的精确度.例如,如果我在纹理上实现了 touchDown(),调整屏幕大小会将纹理区域上的 touchListener 向右或向左移动一些像素,具体取决于调整大小,这显然是不受欢迎的.

Later on when I proceeded with implementing the touchDown() methods for the screen, I found that due to scaling on resize, the co-ordinates on which I had implemented touchDown() would change by a great amount. After working with some code to translate the co-ordinates in accordance with the screen resize, I reduced this amount to a great extent but I wasn't successful to maintain them with pin point accuracy. For example, if I had implemented touchDown() on a texture, resizing the screen would shift the touchListener on the texture region some pixels to the right or left, depending on the resize and this was obviously undesired.

后来我知道舞台类有自己的本机功能来保持纵横比(boolean stretch = false).现在我已经使用 stage 类实现了我的屏幕,它可以很好地保持纵横比.但是在调整大小或不同的屏幕尺寸时,生成的黑色区域总是出现在屏幕右侧;那就是屏幕没有居中,如果黑色区域很大,这会使它变得非常难看.

Later on I came to know that the stage class has its own native functionality to maintain the aspect ratio (boolean stretch = false). Now that I have implemented my screen by using the stage class, the aspect ratio is maintained well by it. However on resize or different screen sizes, 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 quite ugly if the black area is substantially large.

社区成员能帮我解决这个问题吗?

Can any community member help me out to resolve this problem?

推荐答案

现在怎么做:

因为这是这里关于 libgdx 的最著名的问题之一,我会给它一点更新:

LibGDX v1.0 引入了Viewport 来处理这个问题.它更易于使用并且扩展策略是可插入的,这意味着单行代码可以改变行为,您可以使用它并查看哪一个最适合您的游戏.

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.

这篇关于在libGDX中如何处理不同的纵横比?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆