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

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

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

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

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

4d6ae7357a49d42f46b1a45c076c578734d78c27.png

除了 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。

64e618ac903b37c3c88a823da6ded2b7afff74b8.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。

f671858d94e71ac75cd9fe4487799d6e37f8e0a8.png

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

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

e85744b1d025b45b3caf62df0669e0a200c6dd9f.png

首先我们判断游戏是否已结束。如果游戏尚在进行,那在间隔一定时间后,将整条蛇移到下一个位置。这里的间隔时间即影响了贪吃蛇的运动速度,如果希望实现速度越来越快,可以通过修改这个变量实现。整条蛇移动之后,我们需要更新 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

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

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

多谢分享连载了。加油