了解libGDX投影矩阵

use*_*686 20 java camera android projection-matrix libgdx

在过去的几周里,我一直在尝试学习libGDX库.我发现很难,尤其是我第一次尝试游戏开发时,要理解相机/视口关系系统.我被告知使用的一行代码和API提到的是:

    batch.setProjectionMatrix(camera.combined);
Run Code Online (Sandbox Code Playgroud)

尽管进行了4个小时的研究,但我仍然缺乏对此代码功能的完整理解.根据我的基本理解,它"告诉"相机正在寻找的批次.我缺乏理解力令人沮丧和愤怒,如果有人能帮助我,我会很感激.代码片段的另一个问题是我不确定何时需要实现(在render方法中,create方法等).

Xop*_*ppa 22

考虑用相机拍照.例如,使用智能手机相机拍摄公园的长凳照片.当你这样做时,你会在智能手机屏幕上看到公园的长凳.这看起来非常明显,但让我们来看看这涉及到什么.

照片上工作台的位置与拍照时的站立位置有关.换句话说,它是相对于相机.在典型的游戏中,您不会相对于对象放置对象.相反,你把它们放在游戏世界中.在游戏世界和相机之间进行翻译是使用矩阵完成的(这只是一种转换坐标的数学方法).例如,当您将相机向右移动时,工作台会在照片上向左移动.这称为视图矩阵.

图片上工作台的确切位置也取决于工作台和相机之间的距离.至少,它在3D中完成(2D非常相似,所以继续阅读).当它离得更远时它更小,当它靠近相机时它更大.这称为透视投影.您也可以使用正交投影,在这种情况下,对象的大小不会根据到相机的距离而改变.无论哪种方式,公园中工作台的位置和大小都会转换为屏幕上的位置和大小(以像素为单位).例如,公园里的长凳是两米宽,而照片上则是380像素.这称为投影矩阵.

camera.combined表示组合的视图和投影矩阵.换句话说:它描述了游戏世界中的事物应该在屏幕上呈现的位置.

调用batch.setProjectionMatrix(cam.combined);指示批处理使用该组合矩阵.每当值发生变化时,您都应该调用它.这通常resize是在调用时以及移动或以其他方式改变相机时.

如果您不确定,那么您可以在render方法的开头调用它.


Ten*_*r04 13

另一个答案是很好的,但我想一个不同的描述方式可能有助于它点击.

您通常在"世界空间"中处理您的游戏,这是一个类似于现实世界的坐标系.在线性代数中,您可以通过将点的坐标乘以表示两个坐标系之间关系的矩阵,将空间中的点从一个坐标系转换为另一个坐标系.

视图矩阵乘以一个点,将其从世界空间转换为相机空间(相机的视角).投影矩阵用于将点从相机空间转换为屏幕空间(设备屏幕的平面2D矩形).当您update()在Libgdx中调用相机时,它会将最新的位置,方向,视口大小,视野等更改应用到其视图和投影矩阵中,以便可以在着色器中使用它们.

您很少需要在2D中处理相机空间中的内容,因此SpriteBatch不需要单独的视图和投影矩阵.它们可以组合成一个矩阵,直接从世界空间转换到屏幕空间,这已经在相机中自动完成,因此也就是camera.combined矩阵.

SpriteBatch有一个默认的内置着色器,它将此投影矩阵与精灵的所有顶点相乘,以便它们正确映射到平面屏幕.

setProjectionMatrix无论何时移动相机或调整屏幕大小,都应该打电话.

存在第三种类型的矩阵,称为模型矩阵,用于3D东西.模型矩阵描述了模型在世界空间中的方向,比例和位置.因此,它乘以模型中的坐标,将它们从局部空间移动到世界空间.


Cak*_*ray 8

以一个基本的sidecrolling游戏为例.当玩家移动到一侧时,相机会跟随他们.这意味着世界中的对象不一定对应于它们在屏幕上的位置,因为屏幕和世界相对于彼此移动.

这是一个例子:说你的屏幕是100px*100px平方(出于某种原因).将对象放置在位置(50,0),因此它现在位于屏幕的中间和底部.现在假设您将播放器向右移动,整个屏幕平移以跟随播放器.这意味着您之前放置的对象应该在屏幕上向左移动.所以它仍然在世界上的(50,0),因为它实际上并没有相对于其余的景色移动,但它现在应该在屏幕上绘制,例如,(10,0),因为哪个部分屏幕正在看的世界已经改变了.这是"世界空间"(对象在世界中)和"屏幕空间"(在实际显示器上绘制对象)之间的区别.

当您尝试使用a绘制时SpriteBatch,默认情况下假设世界空间坐标与屏幕空间坐标相同:当您说"绘制在(50,0)"时,它将在(50,0)处绘制对象屏幕.即使相机移动,它总是在屏幕上以(50,0)绘制,因此当相机平移时,对象将跟随并保持粘在屏幕上的相同位置.

由于您通常不希望这样,因此您可以给出SpriteBatch一个投影矩阵,它是一个转换矩阵,用于说明如何将屏幕空间坐标转换为世界空间坐标,反之亦然.这样,当你告诉批处理"绘制在(50,0)"时,它可以查看从相机获得的矩阵并看到,由于相机已经移动,(50,0)在世界中实际上意味着( 10,0)在屏幕上,它会在正确的位置绘制你的精灵.