繁体   English   中英

Camera在Libgdx中以及与视口一起工作的方式

[英]How Camera works in Libgdx and together with Viewport

如果您使用LibGdx,它将花费很长时间,直到您进入“摄影机”和视口。 如果您是第一次使用相机和视口,则会遇到一些有关其工作原理和使用方法的问题。 所以:

  • 如何在LibGdx中使用相机? 什么是视口宽度和高度?
  • 什么是视口?如何使用视口?如何将其与相机配合使用?

如何在LibGdx中使用相机? 什么是视口宽度和高度?

首先,重要的是要知道相机适用于世界单位而不适用于像素。 世界单位不是常规单位。 您可以自行定义一个世界单位的数量。 以后更多。

首先,我们创建一个OrthographicCamera一个SpriteBatch和一个Texture

private OrthographicCamera camera;
private SpriteBatch batch;
private Texture img;

@Override
public void create () {
    //We create a OrthographicCamera through which we see 50x50 World Units
    camera = new OrthographicCamera(50,50);
    batch = new SpriteBatch();
    img = new Texture("badlogic.jpg");
}

我们创建一个OrthographicCamera并在“构造函数”中定义如果我们通过此摄像机观察到的世界,可以看到多少个世界单位。 在我们的示例中,“ 50 x 50世界单位”是视口的宽度和高度。 因此,我们创建了一个视口宽度和高度为50的相机。

在render()方法中,我们渲染图像:

@Override
public void render () {
    //Clear the screen (1)
    Gdx.gl.glClearColor(1, 1, 1, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    //Set ProjectionMatrix of SpriteBatch (2)
    batch.setProjectionMatrix(camera.combined);

    batch.begin();
    //Draw image on position 0, 0 with width 25 and height 25 (3)
    batch.draw(img, 0, 0, 25, 25); 
    batch.end();
}

(1)清除屏幕,如果不这样做,则每个Texture都会在另一个上绘制,如果绘制Animation,我们将看到旧的Frames。

(2) batch是我们的抽屉,他绘制我们的图像,动画等。默认情况下,他绘制的世界具有很多世界单位,例如屏幕具有像素,因此在这种情况下1世界单位= 1像素。 但是现在我们将看到50 x 50世界单位与屏幕有多大无关。 要说他应该绘制通过摄像机看到的批处理,我们必须调用: batch.setProjectionMatrix(camera.combined);

(3)现在我们在位置0,0上绘制img ,但是0,0并不意味着在像素位置0,0上,这意味着图像将在世界位置0,0上绘制,宽度和高度也不在像素中,它们是以世界单位为单位,因此img将绘制在0,0 25x25世界单位大位置上。 因此,在50x50的视口中,图像占满整个屏幕的四分之一。

在此处输入图片说明

图像完全按预期填充了整个屏幕的四分之一。 但是,为什么它在右上角而不在左下角?

问题是摄像头的中心在位置0,0上 在此处输入图片说明

因此,我们的图片绘制在位置0,0处,他填充了右上角。 我们必须将摄像机的位置设置为0,0在左下角:

camera = new OrthographicCamera(50,50);
camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0);

在render()方法中,我们必须添加camera.update()因为每次更改位置或缩放比例或相机的其他功能时,都必须更新相机。

现在,图像位于左下方。

像素在哪里?

我们总是谈论世界单位,但像素在哪里? 像素仍然在那里。 如果我们的屏幕尺寸为200 x 200像素,则批处理将始终绘制200 x 200像素。 使用方法batch.setProjectionMatrix(camera.combined); 我们只说一批像素的世界单位是多少。

如果我们有一个200 x 200像素的屏幕,并且我们创建了一个视口为50 x 50世界单位的相机,则SpriteBatch知道1 WorldUnit = 4 Pixels。 现在我们绘制一个25 x 25世界单位大的图像,SpriteBatch知道他必须绘制25 * 4 = 100像素大的图像。

因此像素仍然存在,但是在世界单位中更容易思考。 如果不清楚,这里有一些更详细的描述: Libgdx的世界单位

Box2d

如果您使用Box2d,则在World Units中进行思考也非常重要,因为Box2d与Meters一起使用。 因此,如果您在x轴上创建的力关闭了5,则该物体的速度为5 m / s。

现在使用World Units非常酷,因为您可以说1 World Unit = 1 Meter,因此您可以创建一个宽度为10的对象,并且您知道一秒钟之后,Body将位于对象的中心。 如果您使用像素,则如果屏幕尺寸不同,则会出现问题。

什么是视口?如何使用视口?如何将其与相机配合使用?

现在,我们遇到了有关不同屏幕尺寸的大问题。 突然我们的屏幕尺寸为350 x 200像素,现在图像将被拉伸并且看起来不像以前那么好。

对于这个问题,我们使用视口,一些视口是StretchViewportFitViewportExtendViewport 您可以在这里找到所有视口: https : //github.com/libgdx/libgdx/wiki/Viewports

首先,什么是视口。

想象一下,相机是讲英语的人。 屏幕大小不同的人会说德语,法语,中文等,而视口就是翻译。 译者不会改变英语使用者所说的意思,但他会加以改编,以便其他人都能理解。 相机和视口也一样。 如果您运行该程序,则视口不会说或不会更改您在屏幕上看到的内容。 他只处理您始终在不同的屏幕尺寸上看到相同的内容。 相机可以不使用视口而生活。 一个没有相机的视口。

添加视口对象:

private Viewport viewport;

和resize()方法:

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

拉伸视口

创建一个StretchViewport:

camera = new OrthographicCamera(50, 50);
camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0);
viewport = new StretchViewport(camera.viewportWidth, camera.viewportHeight, camera);

在StretchViewport构造函数中,我们定义视口的宽度和高度以及Camera。

现在,如果具有不同的屏幕尺寸,我们将获得与以前相同的结果,图像将被拉伸。

FitViewport

也许我们不会拉伸图像,我们将对x和y的比例很重要。

x和y的比值表示:是对象2的宽度和1的高度,他将始终是宽度的两倍,例如200x100、30x15但不是20x15。

创建一个FitViewport:

camera = new OrthographicCamera(50, 50);
camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0);
viewport = new FitViewport(camera.viewportWidth, camera.viewportHeight, camera);

现在,图像将始终是正方形。 要查看侧面的条形,请绘制与视口一样大的图像:

batch.draw(img, 0, 0, 50, 50);

在此处输入图片说明 在此处输入图片说明

由于50(宽度)/ 50(高度)= 1,因此图像的比率为1,因此图像始终具有相同的宽度和高度。 侧面的Gdx.gl.glClearColor(1, 1, 1, 1);在我们的视口之外,将以您在此处定义的颜色绘制: Gdx.gl.glClearColor(1, 1, 1, 1);

延伸视口

也许我们不会在侧面放置酒吧,然后我们可以使用ExtendViewport。 ExtendViewport通过在一个方向上扩展世界来保持世界的长宽比而无障碍。 在屏幕上宽度和高度之间的纵横比更大时,意味着您会看到更多的世界。

在屏幕宽高比=(400/200 = 2)的屏幕上,您看到的比在屏幕300x200(300/200 = 1.5)上多;

要显示此内容,请创建一个ExtendViewport并绘制大于视口的Image和第二个小Image:

camera = new OrthographicCamera(50, 50);
camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0);
viewport = new ExtendViewport(camera.viewportWidth, camera.viewportHeight, camera);

// in render() method
batch.begin();
batch.draw(img, 0, 0, 100, 50);
batch.draw(img, -20, 0, 20, 20);
batch.end();

如果现在以200x200的屏幕尺寸启动程序,则会看到:

在此处输入图片说明

如果我们在x轴上调整屏幕的大小,请执行以下操作:

在此处输入图片说明

现在,我们可以在第一个图像上看到更多,并在第二个图像上看到更多,但是比率将始终相同。 仅拉伸图像是因为我们将其绘制为100x50,而不是因为调整大小。

我希望如果您能了解更多信息,阅读并看一些教程并阅读LibGdx Wiki,将会清除一些有关Camera and Viewport的问题: https : //github.com/libgdx/libgdx/wiki

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM