如果您使用LibGdx,它将持续很长时间,直到您进入“摄影机”和视口。如果您是第一次使用相机和视口,则会遇到一些有关其工作原理和使用方法的问题。所以:
答案 0 :(得分:1)
首先,重要的是要知道相机适用于世界单位而不适用于像素。世界单位不是常规单位。您可以自行定义一个世界单位的数量。以后更多。
首先,我们创建一个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位于左下角:
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's World Units
Box2d
如果您使用Box2d,则在World Units中进行思考也非常重要,因为Box2d与Meters一起使用。因此,如果您创建一个在x轴上力为5的Body,则Body的速度为5 m / s。
现在使用World Units非常酷,因为您可以说1 World Unit = 1 Meter,因此您可以创建一个宽度为10的对象,并且您知道一秒钟后,Body将位于对象的中心。如果您使用Pixels,则如果屏幕尺寸不同,则会遇到问题。
现在,我们遇到了有关不同屏幕尺寸的大问题。 突然我们的屏幕尺寸为350 x 200像素,现在图像将被拉伸并且看起来不像以前那么好。
对于此问题,我们使用视口,其中一些视口为StretchViewport
,FitViewport
和ExtendViewport
。您可以在这里找到所有视口:https://github.com/libgdx/libgdx/wiki/Viewports。
首先是什么视口。
想象一下,相机是讲英语的人。屏幕大小不同的人会说德语,法语,中文等,而视口就是翻译。译者不会改变英语使用者所说的意思,但他会加以改编,以便其他人都能理解。相机和视口也一样。如果您运行该程序,则视口不会说或不会更改您在屏幕上看到的内容。他只处理您始终在不同的屏幕尺寸上看到相同的内容。相机可以不使用视口而生活。视口并非没有相机。
添加视口对象:
private Viewport viewport;
和resize()方法:
@Override
public void resize (int width, int height) {
viewport.update(width, height);
}
StretchViewport
创建一个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);
扩展视口
也许我们不会在侧面放置横杠,然后我们可以使用ExtendViewport。 ExtendViewport通过在一个方向上扩展世界来保持世界的长宽比而无障碍。在屏幕上宽度和高度之间的纵横比更大时,您将看到更多的世界。
在屏幕宽高比为400x200 =(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,我希望这将清除有关摄影机和视口的一些问题:https://github.com/libgdx/libgdx/wiki