【问题标题】:Why does my libGDX resize code break camera.unproject?为什么我的 libGDX 调整代码大小会破坏 camera.unproject?
【发布时间】:2013-09-19 05:42:10
【问题描述】:

我在我的 resize 方法中使用以下代码来保持多个屏幕尺寸的纵横比:

@Override
public void resize(int width, int height)
{
    float aspectRatio = (float)width / (float)height;
    float scale = 1f;
    Vector2 crop = new Vector2(0, 0);

    if (aspectRatio > globals.ASPECT_RATIO)
    {
        scale = (float)height / (float)globals.VIRTUAL_HEIGHT;
        crop.x = (width - globals.VIRTUAL_WIDTH * scale) / 2f;
    }
    else if (aspectRatio < globals.ASPECT_RATIO)
    {
        scale = (float)width / (float)globals.VIRTUAL_WIDTH;
        crop.y = (height - globals.VIRTUAL_HEIGHT * scale) / 2f;
    }
    else
    {
        scale = (float)width / (float)globals.VIRTUAL_WIDTH;
    }

    float w = (float)globals.VIRTUAL_WIDTH * scale;
    float h = (float)globals.VIRTUAL_HEIGHT * scale;

    viewport = new Rectangle(crop.x, crop.y, w, h);
}

VIRTUAL_WIDTHVIRTUAL_HEIGHTASPECT_RATIO设置如下:

public final int VIRTUAL_WIDTH = 800;
public final int VIRTUAL_HEIGHT = 480;
public final float ASPECT_RATIO = (float)VIRTUAL_WIDTH / (float)VIRTUAL_HEIGHT;

这对于在屏幕尺寸变化时保持正确的比例非常有效。但是,camera.uproject(我在所有触摸事件之前调用)无法正常工作 - 当调整大小代码将屏幕尺寸更改为 800x480 以外的任何值时,触摸位置不正确。

以下是我在 create() 方法中设置相机的方法:

camera = new OrthographicCamera(globals.VIRTUAL_WIDTH, globals.VIRTUAL_HEIGHT);
camera.setToOrtho(true, globals.VIRTUAL_WIDTH, globals.VIRTUAL_HEIGHT);

这是我的 render() 方法的开始:

camera.update();
Gdx.graphics.getGL20().glViewport((int)viewport.x, (int)viewport.y, 
(int)viewport.width, (int)viewport.height);
Gdx.graphics.getGL20().glClearColor(0, 0, 0, 1);
Gdx.graphics.getGL20().glClear(GL20.GL_COLOR_BUFFER_BIT);

如果我忽略调整大小代码并将glViewport 方法调用设置为Gdx.graphics.getWidth()Gdx.graphics.getHeight()camera.unproject 工作,但我显然失去了纵横比的维护。有人有什么想法吗?

以下是我对触摸事件执行 unproject 的方式:

private Vector3 touchPos = new Vector3(0, 0, 0);

public boolean touchDown (int x, int y, int pointer, int newParam)
{
    touchPos.x = x;
    touchPos.y = y;
    touchPos.z = 0; 
    camera.unproject(touchPos);

    //touch event handling goes here...
}

更新

通过实现一个 Stage 对象,我在这方面取得了一些进步,但它仍然不能完美地工作。

下面是我现在如何在我的 create 方法中设置舞台和相机:

stage = new Stage();
camera = new OrthographicCamera(globals.VIRTUAL_WIDTH, globals.VIRTUAL_HEIGHT);
camera.setToOrtho(true, globals.VIRTUAL_WIDTH, globals.VIRTUAL_HEIGHT);
stage.setCamera(camera);

这是我的调整大小代码:

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, viewportX, viewportY, viewportWidth, viewportHeight);
}

这是我的渲染代码的开始:

stage.getCamera().update();
Gdx.graphics.getGL20().glClearColor(0, 0, 0, 1);
Gdx.graphics.getGL20().glClear(GL20.GL_COLOR_BUFFER_BIT);
spriteBatch.setProjectionMatrix(stage.getCamera().combined);

以下是我处理触摸事件的方式:

private Vector3 touchPos = new Vector3(0, 0, 0);

public boolean touchDown (int x, int y, int pointer, int newParam)
{
    touchPos.x = x;
    touchPos.y = y;
    touchPos.z = 0;
    stage.getCamera().unproject(touchPos);

    //touch event handling goes here...
}

现在,当屏幕处于默认大小并且屏幕被放大时,这可以工作。但是,当屏幕尺寸减小时,触摸点会变得越来越不准确。

【问题讨论】:

    标签: android libgdx


    【解决方案1】:

    设法找到了这个问题的答案。我只需要使用带有 Vector3、viewportX、viewportY、viewportWidth 和 viewportHeight 参数的 camera.unproject 方法调用。所需的视口参数是通过上面显示的调整大小代码计算得出的。

    【讨论】:

      【解决方案2】:

      为了解决您的问题,新的 Stage 系统中已经实施了解决方案。请查看wiki scene2d #viewport。要获得固定的纵横比,您无需手动调整大小和适应。以下是来自 wiki 的带有黑条的示例:

      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, viewportX, viewportY, viewportWidth, viewportHeight);
      }
      

      【讨论】:

      • 谢谢,这非常有用。然而,除了这个问题,我的游戏已经完成,我的代码中没有使用任何 libGDX Stage/Actor 对象。我的每个接受输入的屏幕都有自己的 InputProcessor。考虑到这一点,我怎样才能在对现有代码的改动最少的情况下实现 Stage 对象的这个元素?我在我的 create() 方法中创建并初始化了一个 Stage 对象,并将我的 resize() 代码替换为您发布的 scene2d 示例中的代码。屏幕现在可以正确调整大小并保留纵横比,但调整大小时触摸点仍然不正确。
      • 我在这方面取得了一些进展,但在减小屏幕尺寸时仍然遇到 unproject 问题。有关详细信息,请参阅我编辑的问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-04
      • 1970-01-01
      • 2014-04-09
      • 2011-02-25
      相关资源
      最近更新 更多