Godot在2D环境的仿3D游戏的图层计算

引子

我所用的游戏引擎是Godot,一个用c++写的开源2d/3d游戏引擎,代码托管在github上,拥有一套比较完整的工具,并且使用整个引擎做的游戏对于版本管理工具比较友好,有自己的脚本语言(语法类似Python)。具体的可以到官网上面去看介绍(英文)。

游戏

下面是我做的游戏的一些大致机制的抓屏。


123

可以看到,这是一个固定视角的伪3D游戏,具体操作是通过使用上下左右四个方向来使方块移动,从而是方块达到一定的高度或形状。

问题

我一开始学整个引擎的时候都是在2d环境下制作游戏,而且这个游戏的贴图都是2d的像俗画,所以我在做这个游戏小样的时候就也没有多想,直接在2d环境下开干了。

但是即使我对每个方块都设置各自在整个三维网格中的座标,2d环境能够给我的就只是哪些图片(在我这个游戏中就是方块的贴图)往哪个方向移动,哪些图片先渲染(会被后面的遮住),哪些图片后渲染(不会被遮住)而已。所以为了让整个网格显示正常,必须手动来处理这个网格的渲染顺序,或者说处理好方块的渲染顺序。

引擎

Godot引擎的游戏的制作方法是以“节点”的方式制作,每个节点可以是不同种类的东西,也可以是另外制作好的“节点”,每个独立制作的节点成为“场景”(scene),而节点的顺序,就是引擎渲染的顺序,有撒谎哪个到下依次渲染,所以最下面的节点是最后渲染的。
如果有一个跟节点类型为 Node2D ,字节点是3个TextureRect,那么不论这三个TextureRect的贴图大小如何,位置如何,最下面的TextureRect是不可能被前两个TextureRect遮挡住的。

不过对于 Node2D ,有一个属性是 Z Index ,这个属性是引擎中的 Z 轴,相当于在你手垂直举着一张纸时垂直于直面的一条线。有了这个,就能手动地控制哪些方块在哪些方块的上面了。

设定

游戏内的座标


座标
  • 游戏座标 :是指在上图网格中的座标
  • 引擎座标 :是指在游戏引擎中的座标

计算方式

接下来就是真正的计算方式了,嘿嘿

first try

这里要先弄清楚一点,在上图中最下面的格子中的方块的图层肯定是会比在座标原点的格子的方块图层要高,也就是说最下面的方块的引擎内z轴一定会会比原点的方块高,绝对不会被原点的遮挡的。

那这样的话,即使游戏内是在同一层,也需要根据游戏内x轴和游戏内y轴来计算图层,那在统一层的话是怎么算图层的呢?

从原点开始看吧,在原点的方块上,不论是往游戏内的x轴还是游戏内的y轴方向上移动一格,引擎内的z轴都应该加1(或一个计量),然后在那个格子再继续的话也是加1。那么照这样算,在游戏内z轴相等,也就是同一层的情况下,引擎z轴的计算公式是:

  • 引擎z轴 = 游戏x轴 + 游戏y轴

然后因为游戏内的网格有z轴,也就是类似于”层“的概念,我就非常简单地将每一层叠加起来,所以对于所有方块:

  • 引擎z轴 = 游戏最大x轴 * 游戏最大y轴 * 游戏z轴 + 游戏x轴 + 游戏y轴

这样做的问题

正如你在上面的动图中看到的,方块的移动有时侯会跨”层“。如果使用这样的算法,就会出现方块下降层的时候北原先后面的方块遮挡住,或者上升层的时候遮挡住原先在前面的方块挡住。

finished one

上面这个问题一开始我还没有发现,因为我做一些测试地图的时候,都会做一些比较简单的图来测试。

不过这个问题的解决办法骑士一开始就已经有了,只不过我没有反应过来。那就是既然在同一个”层“上是 x+y ,那么在此基础上,把 x+y 作为一个独立的轴,加上 z ,好像就可以了。

所以对于所有方块:

  • 引擎z轴 = 游戏x轴 + 游戏y轴 + 游戏z轴

这样不论什么情况都不会出现不正确遮挡的问题,下面的两张图能比较好地证明这个:

1.gif

2.gif

写在最后

公式很简单,但是我却花了很多时间去调试第一条公式,不断地调整,试过在每两层之间添加一个过渡层,但是因为引擎本身的图层渲染顺序会有时候看不出来问题。不过有前辈说过,写程序的时候走的弯路都不是弯路。幸好最后都想出来了正确的做法,花的时间应该都是值得的。

你可能感兴趣的:(Godot在2D环境的仿3D游戏的图层计算)