Camera在Libgdx中以及与视口一起工作的方式 [英] How Camera works in Libgdx and together with Viewport

查看:73
本文介绍了Camera在Libgdx中以及与视口一起工作的方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

If you work with LibGdx it goes not long until you come to Camera and viewport. If you work the first time with camera and Viewport you get some questions about how it works and how to use it. So:

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

推荐答案

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

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

How can I use a Camera in LibGdx? What's viewport width and height?

Firstly it's important that you know the Camera works with World units not with Pixels. World units are not a regular Unit. You self can define how much one World Unit is. Later more.

首先,我们创建一个OrthographicCameraSpriteBatchTexture:

First, we create an OrthographicCamera a SpriteBatch and a 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的相机.

We create a OrthographicCamera and in the Constructor we define how many World Units we see if we look through this camera into our world. In our example 50 x 50 World Units these are the viewport width and height. So we have created a Camera with a viewport width and height of 50.

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

In the render() method we render our image:

@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.

(1) Clear the Screen, if we don't do that every Texture will draw over the other and if we draw a Animation we will see the old Frames.

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

(2) The batch is our Drawer he draws our Images, Animations etc. Default he draws a World which has so many World Units like the Screen has Pixels so in this case 1 World Unit = 1 Pixel. But now we will see 50 x 50 World Units doesn't matter how big the screen is. To say the Batch that he should draw what we see through our camera we must call: batch.setProjectionMatrix(camera.combined);

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

(3) Now we draw our img on Position 0,0 But 0, 0 doesn't mean on Pixel position 0,0 it means the Image will be drawn on World position 0,0 also width and height are not in Pixels they are in World units so the img will be drawn on Position 0,0 25x25 World Units big. So on a 50x50 viewport, the image fills one-quarter of the whole screen.

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

The Image fill one-quarter of the whole screen exactly as expected. But why it is on the right top and not on the bottom left?

问题是摄像机的中心指向位置0,0

The Problem is that the center of the Camera point on the position 0,0

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

So our Image is drawn on position 0,0 he fills the top right corner. We must set the position of the camera so 0,0 is in the bottom left corner:

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

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

In the render() method we must add camera.update() because every time we change the position or the scale or what else of the camera we must update the camera.

现在图像位于左下方.

像素在哪里?

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

We always speak about World units but where are the Pixels? The pixels are still there. If we have a Screen size of 200 x 200 pixels the batch will always draw 200 x 200 pixels. With the method batch.setProjectionMatrix(camera.combined); we only say the batch how much World Units are one Pixel.

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

If we have a Screen with 200 x 200 pixels and we create a Camera with a viewport of 50 x 50 world units the SpriteBatch know 1 WorldUnit = 4 Pixels. Now we draw a Image which is 25 x 25 World Units big the SpriteBatch knows he must draw the image 25 * 4 = 100 pixel big.

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

So the pixels still there but it's easier to think in World Units. If it's not clear enough here is a little bit more detailed description: Libgdx's World Units

Box2d

如果使用Box2d,则在World Units中进行思考也非常重要,因为Box2d与Meters一起使用.因此,如果您在x轴上创建的力"为5时,则"Body"的速度为5 m/s.

It's also very important to think in World Units if you use Box2d because Box2d works with Meters. So if you create a Body with a Force off 5 on the x axis, the Body is 5 m/s fast.

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

And now it's very cool to work with World Units because you can say 1 World Unit = 1 Meter so you can create a object with a width of 10 and you know after one second the Body will be in the Center of the Object. If you work with Pixels you will have a Problem if you have a different Screensize.

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

Now we have the big Problem about different Screen sizes. Suddenly we have a Screen size of 350 x 200 pixels, now the Image will be stretched and don't look so nice as before.

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

For this Problem we use Viewports a few Viewports are StretchViewport, FitViewport and ExtendViewport. All viewports you can find here: https://github.com/libgdx/libgdx/wiki/Viewports.

首先是什么视口.

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

Imagine the camera is a speaker who speaks English. Different Screen Sizes are other People who speak German, French, Chinese etc. and the Viewport is the translator. The Translator doesn't change the sense of that what the English Speaker says but he adapts it so the others can understand it. Same are camera and Viewport. Viewport doesn't say or change what you can see on your screen if you run the program. He only handles that you always see the same on different Screen sizes. A Camera can life without Viewport. A Viewport not without Camera.

添加视口对象:

private Viewport viewport;

和resize()方法:

and the resize() method:

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

StretchViewport

创建一个StretchViewport:

Create a 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.

In the StretchViewport Constructor, we define the viewport width and height and the Camera.

现在,如果屏幕尺寸不同,我们将获得与以前相同的结果.

Now we get the same result as before if we have different Screensizes the Images will be stretched.

FitViewport

也许我们不会拉伸图像,所以我们会关心x和y的比率.

Maybe we won't stretch our Images we will matter about the ratio of x and y.

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

The ratio of x and y means: is an Object 2 width and 1 height he will always twice as wide as high for example 200x100, 30x15 but not 20x15.

创建FitViewport:

Create a FitViewport:

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

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

Now the Image will always be a square. To see the Bars on the Side lets draw the Image as big as our viewport:

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

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

The Image has a Ratio of 1 because of 50(width)/50(height) = 1 so the Image will always have the same width and height. The Bars on the side are outside of our Viewport and will be drawn in the color you define here: Gdx.gl.glClearColor(1, 1, 1, 1);

扩展视口

也许我们不会在侧面竖起杠,那么我们可以采用ExtendViewport. ExtendViewport通过在一个方向上扩展世界来保持世界的长宽比而无障碍.在屏幕上宽度和高度之间的纵横比更大时,意味着您会看到更多的世界.

Maybe we won't Bars on the Side then we can take a ExtendViewport. The ExtendViewport keeps the world aspect ratio without bars by extending the world in one direction. Means on a screen where the aspect ratio between width and height are bigger you will see more of the world.

在屏幕宽高比为400x200 =(400/200 = 2)的情况下,您看到的内容比屏幕在300x200的屏幕上(300/200 = 1.5)还要多;

On a screen 400x200 aspect ration = (400/200 = 2) you will see more than on a screen of 300x200 (300/200 = 1.5);

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

To show this create a ExtendViewport and draw the Image bigger than the viewport and a second small 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的屏幕尺寸启动程序,则会看到:

If we now start our Program with a Screen size of 200x200 we see:

如果我们在x轴上调整屏幕大小,则要使屏幕更宽:

And if we resize the Screen on x axis To make the screen wider:

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

Now we can see more off the first Image and additinal the Second image but the ratio will always be the same. The Image is only stretched because we draw it 100x50 not because of resizing.

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

I hope this will clear some Questions about Camera and Viewport if you will learn more, read and look some tutorials and read the LibGdx wiki: https://github.com/libgdx/libgdx/wiki

这篇关于Camera在Libgdx中以及与视口一起工作的方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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