2015-11-14 89 views
12

在过去的几周里,我一直在尝试学习libGDX库。我很难找到它,特别是对于我第一次尝试开发游戏,以了解相机/视口关系系统。一行代码,我已经被告知使用,以及API提到,就是:了解libGDX投影矩阵

batch.setProjectionMatrix(camera.combined); 

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

回答

14

考虑用相机拍照。例如。使用您的智能手机相机在公园里拍张长椅。当你这样做的时候,你会在智能手机的屏幕上看到公园里的长凳。这看起来很明显,但让我们看看这涉及到什么。

图片上的替补的位置是相对于你在哪里拍摄照片时站立。换句话说,它是相对于相机。在典型的游戏中,您不会将对象放置在对象上。相反,你把它们放在你的游戏世界中。在你的游戏世界和你的相机之间进行翻译是通过使用一个矩阵来完成的(这只是一种转换坐标的数学方法)。例如。当您将相机移动到右侧时,长凳会移动到照片的左侧。这被称为视图矩阵。

上的图像的替补的确切位置也取决于长凳和照相机之间的距离。至少,它在3D中(2D非常相似,所以请继续阅读)。当距离较远时,距离较近的摄像机较小。这被称为透视投影。你也可以有一个正交投影,在这种情况下,物体的大小不会根据相机的距离而改变。无论哪种方式,公园的长椅的位置和大小都会转换为屏幕上的像素位置和大小。例如。公园的长凳是两米宽,而照片上是380像素。这被称为投影矩阵。

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

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

如果你不能确定,那么你可以调用你的render方法的开始。

+0

很好的解释。 –

7

其他答案非常好,但我认为描述它的另一种方式可能有助于点击。

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

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

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

SpriteBatch有一个默认的内置着色器,它将这个投影矩阵乘以精灵的所有顶点,这样它们将被正确地映射到纯平屏幕。

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

还有第三种称为模型矩阵的矩阵,用于3D物体。模型矩阵描述了模型在世界空间中的方向,比例和位置。所以它乘以模型中的坐标将它们从本地空间移动到世界空间。

4

例如一个基本的sidescrolling游戏。当玩家移动到一边时,摄像机会跟随它们。这意味着物体在世界中的位置不一定与它们在屏幕上的位置相对应,因为屏幕和世界相对于彼此移动。

下面是一个例子:假设你的屏幕是100px * 100px square(出于某种原因)。您将一个对象放置在位置(50,0)处,因此它现在位于屏幕的中间和底部。现在说你把玩家移到右边,整个屏幕都会跟随玩家。这意味着您之前放置的对象应已在屏幕上向左移动。所以它在世界上仍然是(50,0),因为它实际上并没有相对于其他景物移动,但现在它应该被画在(10,0)屏幕上,因为哪一部分屏幕正在看的世界已经发生了变化。这就是“世界空间”(世界上的一个物体)和“屏幕空间”(在实际显示中绘制物体的位置)之间的区别。

当您尝试使用SpriteBatch进行绘制时,默认情况下会假设世界坐标与屏幕空间坐标相同:当您说“draw at(50,0)”时,它将绘制对象在( 50,0)在屏幕上。即使照相机移动,它总是会在屏幕上以(50,0)绘制,因此当照相机转动时,对象将随之停留在屏幕上的相同位置。

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