经典游戏 ue4 重制(2)贪吃蛇

今天介绍一下使用 UE4 实现贪吃蛇的基本机制。

我们仍然使用 Top Down 的 BP 项目模版。删除原有的 TopDownCharacter 等不必要元素,并且添加一个俯视摄像机。

Map 中还可看到一个红色边框的 Actor。我们命名为 SpawnVolume,它包含一个 Box,用来指定贪吃蛇食物出现的范围。

由于我们不需要 PlayerStart,所以可以将 Default Pawn Class 置空,整个项目的 GameMode 配置如下。

除了 SpawnVolume 之外,我们还会新建两个 Actor,其一为 BP_Item,即贪吃蛇的食物,其二为 BP_Part,定义了贪吃蛇的一节身体。让我们先看一下 BP_Item。

BP_Item 的 Component 还是简单的一个 Static Mesh,在事件中,我们需要响应 BP_Item
与 BP_Part 的碰撞。碰撞之后,BP_Item 会销毁自身,同时设置告知 Controller 需要 Spawn 一节身体,最后再 Spawn 出一个食物。

既然说到 Spawn 食物,那我们顺便看下 Controller 的 SpawnItem。

Image02.png

SpawnItem 中,我们取得之前提到的 SpawnVolume 的中心点和大小,并且在其中随机生成一个点,然后在这个点的位置 Spawn 出一个 BP_Item 即可。

看过了 BP_Item,让我们再来看看 BP_Part。同样,BP_Part 里只设置了一个 StaticMesh,在 Event Graph 中,我们首先添加碰撞事件。

其中所做的操作是,如果贪吃蛇撞上了自己的身体,则调用 Controller 中的 Death 事件。我们并没有处理当贪吃蛇撞上围墙时的情况,但是方式是相同的。

Death 中的操作如下,

主要是引爆蛇的身体,并且通过设置 isGameOver 标记游戏结束。

BP_Item 和 BP_Part 的处理都比较简单,重活都有 Controller 处理了。在 Controller 中直接添加游戏机制或者保存游戏状态可能不是最好的实践,不过这里为了简化流程就一并放在一起了。

我们在 Controller 中添加了如下变量。

Image07.png

其中 SnakeParts 是个由 BP_Part 组成的数组,我们在其中保存贪吃蛇的身体。NeedSpawnNewPart 表示需要在下一个运动周期内 Spawn 一节新身体,我们刚才已经在 BP_Item 的碰撞事件中见过了。Positions 会保存贪吃蛇各节身体的位置。有同学可能会觉得 Positions 数组和 SnakeParts 数组有些重复,我们的确可以只使用一个数组即完成贪吃蛇的运动,不过为了实现的逻辑简单,这里采用了两个数组。除此之外,SpawnPosition 保存了下一个运动周期新身体的位置,isGameOver 我们之前已经见过。最后的 Velocity 表示贪吃蛇的运动方向,和变量名稍有不符,在意的同学可自行修改。

为 Velocity 设置初始值,将决定贪吃蛇一开始的运动方向,我们也可以使用 WASD 控制。

Begin Play 如下,

操作是 Spawn 蛇的第一节身体,更新一下 Positions 数组,并且 Spawn 第一个食物。

让我们具体来看一下 UpdatePositions。

首先保险起见我们清空一下数组,其次对于 SnakeParts 中的每个元素,得到它的位置,并且添加到 Positions 中。

除了 Begin Play 和按键响应外,我们在 Controller 中通过 Tick 来完成蛇的运动。

首先我们判断游戏是否已结束。如果游戏尚在进行,那在间隔一定时间后,将整条蛇移到下一个位置。这里的间隔时间即影响了贪吃蛇的运动速度,如果希望实现速度越来越快,可以通过修改这个变量实现。整条蛇移动之后,我们需要更新 Positions 数组,如有需要则 Spawn 新的身体,以及更新 SpawnPosition。

Move Snake 是这次比较复杂的函数,内容如下。

主要操作是,针对 SnakeParts 的每个元素进行循环,如果是第一个元素,即贪吃蛇的头,那就根据 Velocity 移动到新的位置,而对于贪吃蛇的身体,则根据 Positions 中保存的位置,将它移动到上一节身体的位置。

MoveSnake 完成后,SnakeParts 中贪吃蛇的身体已经移动到新的位置,而 Positions 中仍然是上一个周期的位置,所以我们需要在之后调用 UpdatePositions。

SpawnNewPart 负责生成一节贪吃蛇的身体,内容如下。

即在 SpawnPosition 的位置,Spawn 一个 BP_Part,将其加入 SnakePart,最后将标记位重置。

在 UpdatePosition 和 SpawnNewPart 完成后,我们需要将当前蛇的最后一节身体的位置,置为下一周期 Spawn 新身体的位置。这个操作在 UpdateSpawnPosition 中完成。

总结一下,Controller 中我们添加了如下事件和函数。

Image15.png

至此贪吃蛇基本完成。这里的 SpawnItem 做成了事件,其实直接用函数也行,因为我们在其中并未调用 Delay 等方法。

下次介绍纵轴射击游戏。

支持一下!!nice work

楼主辛苦了,能把自己的经验分享出来的都是英雄,感谢!

特地前来膜拜! 感谢分享教程~;)

多谢分享连载了。加油