实现2D地图的高度效果,需要解决的关键问题就是地图边缘的碰撞,其次是地图与角色的显示层级关系。


(资料图)

为解决碰撞关系,可以利用角色的Collision属性和TileMap的Physical Layers属性,两者对应的Layer、Mask值相同时有碰撞关系,不同时没有碰撞关系。而显示层级则可以通过修改TileMap的Layers中某个地图层级的Y Sort Origin值,如果去修改玩家的Y Sort Origin属性的话,可能会影响与其他地图层的显示顺序。

为TileMap添加至少两个Physical Layers,并选择不同的值,对应这两个值,角色的Collision属性也要点亮相同的值。

首先解决从某些地形的上方或者下方穿越过去,比如两个地图之间的桥面、自然形成的石拱门(这两种情况下,如果需要穿越的带碰撞的景物不大的话,可以给这些地图块创建备选图块,然后不要碰撞,替换掉这些带碰撞的地图块就可以)。

被穿越的地形使用的是layer_0的碰撞属性,不可穿越的地形使用的是layer_1的碰撞属性,那么当角色某个区域后,将角色Collision的Layer、Mask的1给禁用即可,_collision_layer_value(1, false),离开该区域后再启用。

TileMap的Custom Data(自定义数据)。在TileMap中新建Custom Data Layers,选择好Type为bool。在TileSet中将桥面的该自定义属性修改为True,如果桥面和下层碰撞靠的很近,以至于角色走不上桥面,可以新建一些地图块,将自定义属性修改为True铺在桥上(至少要全覆盖被穿越的地形)。

以上参考:/6YT0UafdrOc

当然也可以使用Area2D来制作,见下文。

上面的方法适合的是单纯从上面或者下面穿过地形,如果地形既要被穿过也可以让角色在上层或者下层行动,就需要用其他方法了,因为Custom Data不管角色在上还是下都会触发,修改角色的碰撞属性后,可能会影响角色所在层应该正常存在的碰撞,而如果通过Custom Data检测后修改地图块的碰撞属性,是可行的,但会导致游戏卡顿,因为Custom Data是在process中不断通过角色位置获取信息的,每次都要遍历所有地图块并确认属性。所以需要一个能够一次修改地图块属性的方法,那就是Area2D来检测角色是否要进行穿越地形。

如果地形存在多个出入口,记得每个出入口都要安排上Area2D。

总结:

利用Custom Data来做地图高低效果,需要不停检索角色所在位置地图块的信息,匹配上信息后,通过修改角色的Collision Layer和Collision Mask的值来控制角色和地图块的碰撞关系。

利用Custom Data不适合修改地图块属性,每帧遍历会非常占资源,适合单纯穿过上层或下层地图的时候使用,因为Custom Data地图块要铺在碰撞的周围和上面,所以在穿过地图时,会把正在穿过的那层地图该有的碰撞关系都给取消掉。

Area2D来做地图高低效果,获得进出Area2D的位置,来判断下一步做何操作。通过修改地图的某个Physical Layers的值来控制地图块与角色之间的碰撞关系,通过修改某个层级的地图的y sort origin值来控制地图块与玩家的前后关系。

set_physics_layer_collision_layer()和set_layer_y_sort_origin()在修改地图属性的时候,要注意周围使用了相同物理层、地图层的同类型的地图块,在这些不需要修改的地图块上可以加一层透明的其他层级的带碰撞的地图块。

地图块的碰撞不要画的花里胡哨的,一是操作起来被各种歪七八扭的地形拦住很不舒服,二是不规则的碰撞配上这两种做地图高低效果的方法非常容易卡在某个奇葩的碰撞角落里。

如果是有进出口的地形,在进出口都要安排上Area2D。

注意角色通过Area2D的方向,左右、上下。进入Area2D内又从进来的方向出去,就不需要变更碰撞关系和显示层级。

关键词: