在过去的几周里,我一直在尝试学习libGDX库。我发现很难,尤其是我第一次尝试游戏开发时,要理解相机/视口关系系统。我被告知要使用的一行代码和API提到:
batch.setProjectionMatrix(camera.combined);
尽管进行了4个小时的研究,但我仍然缺乏对此代码功能的完整理解。根据我的基本理解,它“告诉”相机正在寻找的批次。我缺乏理解力令人沮丧和愤怒,如果有人能帮助我,我会很感激。代码片段的另一个问题是我不确定何时需要实现(在render方法中,create方法等)。
答案 0 :(得分:21)
考虑用相机拍照。例如。使用智能手机相机拍摄公园长椅的照片。当你这样做时,你会在智能手机屏幕上看到公园的长凳。这似乎非常明显,但让我们来看看这涉及到什么。
照片上工作台的位置与拍摄照片时的站立位置有关。换句话说,它是相对于相机。在典型的游戏中,您不能相对于对象放置对象。相反,你把它们放在游戏世界中。在游戏世界和相机之间进行翻译是使用矩阵完成的(这只是一种变换坐标的数学方法)。例如。当您将相机向右移动时,工作台会在照片上向左移动。这称为视图矩阵。
图片上工作台的确切位置还取决于工作台与相机之间的距离。至少,它在3D中完成(2D非常相似,所以继续阅读)。当它离得更远时它更小,当它靠近相机时它更大。这称为透视投影。您也可以使用正交投影,在这种情况下,对象的大小不会根据到相机的距离而改变。无论哪种方式,公园中工作台的位置和大小都会转换为屏幕上的位置和大小(以像素为单位)。例如。公园里的长凳是两米宽,照片上是380像素。这称为投影矩阵。
camera.combined
表示组合的视图和投影矩阵。换句话说:它描述了游戏世界中的事物应该在屏幕上呈现的位置。
调用batch.setProjectionMatrix(cam.combined);
指示批处理使用该组合矩阵。每当值发生变化时,您都应该调用它。这通常是在调用resize
时以及移动或以其他方式改变相机时。
如果您不确定,可以在render
方法的开头调用它。
答案 1 :(得分:12)
另一个答案非常好,但我想出一种不同的方式来描述它可能有助于它点击。
你通常在“世界空间”中处理你的游戏,这是一个类似于现实世界的坐标系。在线性代数中,您可以通过将点的坐标乘以表示两个坐标系之间关系的矩阵,将空间中的点从一个坐标系转换为另一个坐标系。
视图矩阵乘以一个点,将其从世界空间转换为相机空间(相机的视角)。投影矩阵用于将点从相机空间转换为屏幕空间(设备屏幕的平面2D矩形)。当您在Libgdx中的相机上调用update()
时,它会将最新的位置,方向,视口大小,视野等更改应用到其视图和投影矩阵,以便它们可以在着色器中使用。
您很少需要在2D中处理相机空间中的内容,因此SpriteBatch不需要单独的视图和投影矩阵。它们可以组合成一个矩阵,直接从世界空间转换到屏幕空间,这已经在相机中自动完成,因此是camera.combined
矩阵。
SpriteBatch有一个默认的内置着色器,它将此投影矩阵与精灵的所有顶点相乘,以便它们正确映射到平面屏幕。
每当您移动相机或调整屏幕大小时,都应该致电setProjectionMatrix
。
第三种类型的矩阵叫做模型矩阵,用于3D东西。模型矩阵描述了模型在世界空间中的方向,比例和位置。因此,它乘以模型中的坐标,将它们从局部空间移动到世界空间。
答案 2 :(得分:8)
以一个基本的sidecrolling游戏为例。当玩家移动到一侧时,相机会跟随他们。这意味着世界上的物体并不一定与屏幕上的物体相对应,因为屏幕和世界相对于彼此移动。
这里有一个例子:说你的屏幕是100px * 100px平方(出于某种原因)。您将对象放置在位置(50,0),因此它现在位于屏幕的中间和底部。现在假设您将播放器向右移动,整个屏幕平移以跟随播放器。这意味着您之前放置的对象应该在屏幕上向左移动。所以它仍然在世界上的(50,0),因为它实际上并没有相对于其他景物移动,但现在应该在(10,0)上绘制屏幕,因为屏幕正在看的世界的哪个部分已经改变。这是" worldspace"之间的区别。 (对象在世界中)和"屏幕空间" (在实际显示器上绘制对象的位置)。
当您尝试使用SpriteBatch
进行绘制时,默认情况下假设世界空间坐标与屏幕空间坐标相同:当您说"绘制在(50,0)和#34; ,它将在屏幕上的(50,0)处绘制对象。即使相机移动,它也总是在屏幕上绘制(50,0),因此当相机平移时,对象将跟随并保持粘在屏幕上的相同位置。
由于您通常不想要,因此您需要提供SpriteBatch
投影矩阵,这是一个转换矩阵,用于说明如何将屏幕空间坐标转换为世界空间坐标,以及反之亦然。这样,当你告诉批次"在(50,0)"画画时,它可以查看从相机获得的矩阵并看到,因为相机已移动,(50,0)在世界上实际上意味着(10,0)在屏幕上,它将在正确的位置绘制你的精灵。