Java 摄影机在Libgdx中以及与视口一起工作的方式
如果您使用LibGdx,很快就会进入摄影机和视口。如果您第一次使用摄影机和视口,您会遇到一些有关其工作原理和使用方法的问题。因此: 如何在LibGdx中使用相机?视口的宽度和高度是多少? 什么是视口,我如何使用它以及它如何与摄影机一起工作? 如何在LibGdx中使用相机?视口的宽度和高度是多少? 首先,重要的是你要知道相机是用世界单位工作的,而不是像素。世界单位不是常规单位。你可以自己定义一个世界单位是多少。以后再谈 首先,我们创建正交摄影机SpriteBatch和纹理: 我们创建一个正交摄影机,在构造器中定义通过该摄影机观察世界时看到的世界单位数。在我们的示例中,50 x 50世界单位是视口宽度和高度。 因此,我们创建了一个视口宽度和高度为50的摄影机 在渲染方法中,我们渲染图像:Java 摄影机在Libgdx中以及与视口一起工作的方式,java,camera,libgdx,viewport,Java,Camera,Libgdx,Viewport,如果您使用LibGdx,很快就会进入摄影机和视口。如果您第一次使用摄影机和视口,您会遇到一些有关其工作原理和使用方法的问题。因此: 如何在LibGdx中使用相机?视口的宽度和高度是多少? 什么是视口,我如何使用它以及它如何与摄影机一起工作? 如何在LibGdx中使用相机?视口的宽度和高度是多少? 首先,重要的是你要知道相机是用世界单位工作的,而不是像素。世界单位不是常规单位。你可以自己定义一个世界单位是多少。以后再谈 首先,我们创建正交摄影机SpriteBatch和纹理: 我们创建一个正交摄影机
@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清除屏幕,如果我们不这样做,每个纹理将绘制在另一个纹理上,如果我们绘制动画,我们将看到旧帧
2该批是我们的抽屉,他绘制我们的图像、动画等。默认情况下,他绘制的世界具有如此多的世界单位,如屏幕具有像素,因此在本例中,1世界单位=1像素。但现在我们将看到,50 x 50世界单位与屏幕大小无关。要说他应该画我们通过相机看到的那一批,我们必须称之为:Batch.setprojectionmatrix.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);
在渲染方法中,我们必须添加camera.update,因为每次更改相机的位置或比例或其他内容时,我们都必须更新相机
现在,图像位于左下角
像素在哪里
我们总是谈论世界单位,但像素在哪里?像素仍然存在。如果我们有一个200 x 200像素的屏幕大小,该批将始终绘制200 x 200像素。使用batch.SetProjectionMatrix.combined方法;我们只说一个像素的世界单位是多少
如果我们有一个200 x 200像素的屏幕,并且我们创建了一个具有50 x 50世界单位视口的相机,那么SpriteBatch知道1世界单位=4像素。
现在我们画一个25 x 25世界单位的图像SpriteBatch知道他必须画25*4=100像素大的图像
所以像素仍然存在,但更容易用世界单位来思考。
如果不够清楚,这里有更详细的描述:
Box2d
如果使用Box2d,以世界单位思考也是非常重要的,因为Box2d与米一起工作。因此,如果在x轴上创建一个力为5的物体,该物体的速度为5 m/s
现在使用世界单位非常酷,因为你可以说1个世界单位=1米,这样你就可以创建一个宽度为10的物体,你知道一秒钟后物体会在物体的中心。如果你使用像素,如果你有不同的屏幕尺寸,你就会有问题
什么是视口,我如何使用它以及它如何与摄影机一起工作?
现在我们有一个关于不同屏幕大小的大问题。
突然,我们的屏幕大小变成了350 x 200像素,现在图像会被拉伸,看起来不像以前那么漂亮了
对于这个问题,我们使用了几个视口:StretchViewport、FitViewport和ExtendViewport。您可以在此处找到的所有视口:
首先,什么是视口
想象摄像机是一个说英语的人。不同的屏幕大小是说德语、法语、汉语等的其他人,视口是翻译器。译者不会改变说英语的人所说的话的意思,但他会调整它,以便其他人能理解它。摄影机和视口是相同的。如果运行程序,“视口”不会显示或更改屏幕上显示的内容。他只处理你在不同屏幕尺寸上看到的相同内容。摄影机可以在没有视口的情况下使用。没有摄影机的视口
添加视口对象:
private Viewport viewport;
以及调整大小的方法:
@Override
public void resize (int width, int height) {
viewport.update(width, height);
}
拉伸视口
创建拉伸视口:
camera = new OrthographicCamera(50, 50);
camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0);
viewport = new StretchViewport(camera.viewportWidth, camera.viewportHeight, camera);
在StretchViewport构造函数中,我们定义视口宽度和高度以及Ca
梅拉
现在我们得到了和以前一样的结果,如果我们有不同的屏幕大小,图像将被拉伸
FitViewport
也许我们不会拉伸我们的图像,我们会关心x和y的比例
x和y的比率意味着:是一个2宽1高的对象,他将始终是高的两倍,例如200x100、30x15,但不是20x15
创建一个新的视口:
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);
由于50width/50height=1,图像的比率为1,因此图像的宽度和高度始终相同。侧面的条形图位于视口之外,将以您在此处定义的颜色绘制:Gdx.gl.glClearColor1,1,1,1
扩展可视端口
也许我们不会在边上横杆,然后我们可以去一个延伸的观景台。ExtendViewport通过向一个方向扩展世界来保持世界纵横比,而不使用横杆。这意味着在屏幕上,宽高比越大,你可以看到更多的世界
在400x200纵横比=400/200=2的屏幕上,您将看到比300x200 300/200=1.5的屏幕更多的内容
要显示这一点,请创建一个ExtendViewport并绘制比视口大的图像和第二个小图像:
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,我希望这将澄清有关摄影机和视口的一些问题:如何在LibGdx中使用摄影机?视口的宽度和高度是多少?
首先,重要的是你要知道相机是用世界单位工作的,而不是像素。世界单位不是常规单位。你可以自己定义一个世界单位是多少。以后再谈
首先,我们创建正交摄影机SpriteBatch和纹理:
我们创建一个正交摄影机,在构造器中定义通过该摄影机观察世界时看到的世界单位数。在我们的示例中,50 x 50世界单位是视口宽度和高度。
因此,我们创建了一个视口宽度和高度为50的摄影机
在渲染方法中,我们渲染图像:
@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清除屏幕,如果我们不这样做,每个纹理将绘制在另一个纹理上,如果我们绘制动画,我们将看到旧帧
2该批是我们的抽屉,他绘制我们的图像、动画等。默认情况下,他绘制的世界具有如此多的世界单位,如屏幕具有像素,因此在本例中,1世界单位=1像素。但现在我们将看到,50 x 50世界单位与屏幕大小无关。要说他应该画我们通过相机看到的那一批,我们必须称之为:Batch.setprojectionmatrix.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);
在渲染方法中,我们必须添加camera.update,因为每次更改相机的位置或比例或其他内容时,我们都必须更新相机
现在,图像位于左下角
像素在哪里
我们总是谈论世界单位,但像素在哪里?像素仍然存在。如果我们有一个200 x 200像素的屏幕大小,该批将始终绘制200 x 200像素。使用batch.SetProjectionMatrix.combined方法;我们只说一个像素的世界单位是多少
如果我们有一个200 x 200像素的屏幕,并且我们创建了一个具有50 x 50世界单位视口的相机,那么SpriteBatch知道1世界单位=4像素。
现在我们画一个25 x 25世界单位的图像SpriteBatch知道他必须画25*4=100像素大的图像
所以像素仍然存在,但更容易用世界单位来思考。
如果不够清楚,这里有更详细的描述:
Box2d
如果使用Box2d,以世界单位思考也是非常重要的,因为Box2d与米一起工作。因此,如果在x轴上创建一个力为5的物体,该物体的速度为5 m/s
现在使用世界单位非常酷,因为你可以说1个世界单位=1米,这样你就可以创建一个
物体的宽度为10,你知道一秒钟后物体将位于物体的中心。如果你使用像素,如果你有不同的屏幕尺寸,你就会有问题
什么是视口,我如何使用它以及它如何与摄影机一起工作?
现在我们有一个关于不同屏幕大小的大问题。
突然,我们的屏幕大小变成了350 x 200像素,现在图像会被拉伸,看起来不像以前那么漂亮了
对于这个问题,我们使用了几个视口:StretchViewport、FitViewport和ExtendViewport。您可以在此处找到的所有视口:
首先,什么是视口
想象摄像机是一个说英语的人。不同的屏幕大小是说德语、法语、汉语等的其他人,视口是翻译器。译者不会改变说英语的人所说的话的意思,但他会调整它,以便其他人能理解它。摄影机和视口是相同的。如果运行程序,“视口”不会显示或更改屏幕上显示的内容。他只处理你在不同屏幕尺寸上看到的相同内容。摄影机可以在没有视口的情况下使用。没有摄影机的视口
添加视口对象:
private Viewport viewport;
以及调整大小的方法:
@Override
public void resize (int width, int height) {
viewport.update(width, height);
}
拉伸视口
创建拉伸视口:
camera = new OrthographicCamera(50, 50);
camera.position.set(camera.viewportWidth / 2, camera.viewportHeight / 2, 0);
viewport = new StretchViewport(camera.viewportWidth, camera.viewportHeight, camera);
在StretchViewport构造函数中,我们定义视口宽度和高度以及摄影机
现在我们得到了和以前一样的结果,如果我们有不同的屏幕大小,图像将被拉伸
FitViewport
也许我们不会拉伸我们的图像,我们会关心x和y的比例
x和y的比率意味着:是一个2宽1高的对象,他将始终是高的两倍,例如200x100、30x15,但不是20x15
创建一个新的视口:
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);
由于50width/50height=1,图像的比率为1,因此图像的宽度和高度始终相同。侧面的条形图位于视口之外,将以您在此处定义的颜色绘制:Gdx.gl.glClearColor1,1,1,1
扩展可视端口
也许我们不会在边上横杆,然后我们可以去一个延伸的观景台。ExtendViewport通过向一个方向扩展世界来保持世界纵横比,而不使用横杆。这意味着在屏幕上,宽高比越大,你可以看到更多的世界
在400x200纵横比=400/200=2的屏幕上,您将看到比300x200 300/200=1.5的屏幕更多的内容
要显示这一点,请创建一个ExtendViewport并绘制比视口大的图像和第二个小图像:
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,我希望这将澄清有关摄影机和视口的一些问题: