屏幕,分辨率,相机,视口混乱

时间:2015-07-01 21:44:44

标签: android opengl-es libgdx

我已经阅读了一些关于手机上的分辨率,屏幕,视口和相机的文章,但我现在更加困惑,我以前就是这样。你可以帮我跟上问题并处理它,因为目前我正在开发手机游戏,但没有任何成功。我正在使用LibGDX。

  

关于下面的回答,我改变了我的计划(感谢Xoppa的解释:)

新代码:

    @Override
    public void create () {
        orthographicCamera = new OrthographicCamera();
        fillViewport = new FillViewport(960, 600, orthographicCamera);      
        orthographicCamera.position.set(orthographicCamera.viewportWidth * 0.5f, orthographicCamera.viewportHeight * 0.5f, 0);
        fillViewport.apply();
    }

@Override
    public void render () {
        Gdx.gl.glClearColor(0.22f, 0.22f, 0.22f, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        ...
}

@Override
    public void resize (int width, int height) {
        fillViewport.update(960, 600);
        orthographicCamera.position.set(960 * 0.5f, 600 * 0.5f, 0);
    }
  

但结果是一样的。

输出: enter image description here 两个小点是我的球员。 :(

  

即使我更改了视口分辨率,我的播放器尺寸也不会改变。唯一改变的是视口的可见分辨率,在它后面我没有看到mz玩家。我怀疑它是为了更好的想象力(价值只是想象力)。

我的球员的物理身体:

public Character(Vector2 startPosition) {
    BodyDef bodyDef = new BodyDef();
    bodyDef.type = BodyType.DynamicBody;
    bodyDef.position.set(startPosition);

    // Create our body in the world using our body definition
    body = Physic.gameWorld.createBody(bodyDef);

    // Create a circle shape and set its radius to 6
    CircleShape circle = new CircleShape();
    circle.setPosition(new Vector2());
    circle.setRadius(0.39f);

    // Create a fixture definition to apply our shape to
    FixtureDef fixtureDef = new FixtureDef();
    fixtureDef.shape = circle;
    fixtureDef.density = 1f;

    // Create our fixture and attach it to the body
    body.createFixture(fixtureDef);
    circle.dispose();
}
  

即使我改变圆的半径,身体也需要更多的能量来操纵,身体也不够大。当然我不能将半径设置为大于10f的值,因为Box2D doc不推荐它。

但是我没有看到任何东西,当我运行它,或者创建的物理世界对象太小或扁平时(我认为物理世界配置和初始化是好的;圆形物理对象的半径是0.39)。或者我在代码,某些陈述或其他任何内容中遗漏了某些内容?

但我认为我对正确理解上述问题存在问题。

你能帮我解释一下还是解释一下?

1 个答案:

答案 0 :(得分:0)

首先确保了解相机和视口的功能和作用。也许这个例子可能有所帮助:

想象一下,你在公园里,用相机/智能手机拍照树和长凳拍照。例如,工作台是3米宽,半米高和深度。树可能是例如半米宽,10米高。现在,如果您查看相机/智能手机屏幕上的照片,那么您将看到工作台不再宽3米,而是只有几毫米宽。实际尺寸取决于您设置相机的方式(例如缩放)以及照片的分辨率(以像素为单位)以及您正在观看的屏幕密度。

实际上在上面的例子中,工作台和树有两种不同的尺寸:物理世界中公园的实际尺寸以及屏幕上你正在观看照片的尺寸。当然树和长凳实际上并没有根据照片缩小,它们保持相同的大小。照片上的大小只是树和工作台的投影的大小。

投影实际上是根据各种相机设置(如变焦,位置等)将世界物体转换到屏幕上。

公园比你拍摄照片的部分要大得多。当您拍摄照片时,您决定要将哪个部分的公园(物理世界)投影到照片上。我们称之为公园的视口。

同样,您也没有无限存储来投影照片,您必须定义要投影到的部分(照片的分辨率)。我们称之为照片的视口。

公园的视口以实际单位表示,例如米或英寸,例如照片的视口以像素(您将其设置为的分辨率)表示。

制作游戏时,您通常不会制作照片,而是渲染到屏幕。因此,照片的视口称为屏幕视口。在制作游戏时,你的公园甚至可能不存在,你的游戏世界是虚拟的。因此,公园的视口被称为虚拟视口

在一个小方面注意:像素总是整数,因此 screenviewport 总是用int表示。世界单位(如米或英寸)可以是小数,因此 virtualviewport 始终以float表示。

libgdx的Camera类完全按照上面描述的那样执行,它将虚拟世界投影到屏幕上。但是,在实践中会遇到一些问题。例如。并非每个屏幕都具有相同的宽高比。因此,您需要定义如何应对宽高比的差异。例如。添加黑条,扩展虚拟世界或拉伸它等等。

Viewport类libgdx通过实现various strategies解决了这个问题,您可以从中选择如何定义virtualviewport和screenviewport。为此,它会为您封装(并管理)一个摄像头。

在你的代码中,你在构造函数中给它一个OrthographicCamera来管理,这通常用于2D游戏。但是,您在构造函数中设置OrthographicCamera virtualviewport 会被覆盖。因为您选择使用ScreenViewport。这是一个实现,它使 virtualviewport (公园的一部分)与 screenviewport (屏幕的一部分)相同。

您不太可能想要使用该视口实现。相反,你可能想要使用例如FillViewport

public void create () {
        viewport = new FillViewport(50f, 50f);
}

这会创建一个 virtualviewport ,如果需要保持宽高比,它会增长。 50乘50是世界单位,例如米或英寸。

现在我们需要告诉视口使用哪个 screenviewport 。这取决于设备屏幕的大小,因此最好在resize方法中进行设置。

public void resize (int width, int height) {
    viewport.update(width, height);
}

您可以删除这些方法的所有其他代码,您不需要它们。您无需在渲染方法中更新相机。您可以像往常一样使用视口。如果您需要直接访问相机(但不要修改它,只能读取它的投影矩阵),那么您可以使用:

viewport.getCamera()
相关问题