pygame 构建游戏世界(二) 蚂蚁实体类 附带完整代码

426 阅读7分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第28天,点击查看活动详情

蚂蚁实体类

在为蚂蚁建模大脑之前,让我们看一下蚂蚁类(参见清单 7-5)。它派生自游戏实体,因此它将具有游戏实体的所有功能,以及我们添加到其中的任何其他功能。

image.png

image.png

我们的 Ant 类 (init) 的构造函数首先调用基类的构造函数,其行为“游戏实体”。初始化(自我,世界,“蚂蚁”,图像)。我们必须这样称呼它,因为如果我们要称呼自己。初始化的蟒蛇会调用

Ant 中的构造函数-和最终进入无限循环!蚂蚁构造函数中的其余代码将创建状态机(在下一节中介绍),并将名为 carry_image 的成员变量设置为 None。此变量由携带函数设置,用于存储蚂蚁携带的物体的图像;它可能是一片叶子或一只死蜘蛛。如果调用 drop 函数,它将carry_image设置回 None,并且不再绘制。

由于能够携带其他图像,蚂蚁在渲染精灵时有额外的要求。除了蚂蚁自己的图像之外,我们还想绘制蚂蚁携带的图像,因此蚂蚁有一个专门的渲染版本,它调用基类中的渲染函数,然后渲染carry_image(如果未设置为 None)。

构建大脑

每只蚂蚁的状态机中将有四种状态,这应该足以模拟类似蚂蚁的行为。定义状态机的第一步是弄清楚每个状态应该做什么,即状态的操作(参见表7-1)。

image.png

image.png

我们还需要定义连接状态的链接。它们采用条件的形式,以及在满足条件时要切换到的状态的名称。例如,探索状态有两个这样的链接(参见表 7-2)。

image.png

一旦我们定义了状态之间的联系,我们就有了一个状态机,可以用作实体的大脑。图 7-3 显示了我们将为 ant 构建的完整状态机。像这样在纸上绘制状态机是可视化它们如何组合在一起的好方法,并且在您需要将其转换为代码时会有所帮助。

image.png

让我们将其付诸实践,并为状态机创建代码。我们将首先为单个状态定义一个基类(参见清单 7-6)。稍后,我们将为整个状态机创建另一个类,该类将管理它所包含的状态。

基 State 类除了在构造函数中存储状态名称之外,实际上不执行任何其他操作。状态中的其余函数不执行任何操作 - 传递

关键字只是告诉 Python 您有意将函数留空。我们需要这些空函数,因为并非所有我们将要构建的状态都将实现所有基类中的函数。例如,浏览状态没有退出操作。当我们实现 AntStateExploring 类时,我们可以省略退出操作函数,因为它将安全地回退到基类(State)中函数的无所事事版本。

image.png

在构建状态之前,我们需要构建一个管理它们的类。StateMachine 类(参见清单 7-7)将每个状态的实例存储在字典中,并管理当前活动状态。think 函数每帧运行一次,并在活动状态上调用 do 操作 - 执行状态设计要执行的任何操作;探索状态将随机选择步行到的地方,搜索状态将向叶子移动,依此类推。think 函数还调用状态的check_conditions函数来检查所有链接条件。

如果检查条件返回一个字符串,将选择新的活动状态,并将运行任何退出和进入操作。

image.png

image.png

现在我们有一个功能正常的状态机类,我们可以通过从 State 类派生并实现其某些函数来开始实现每个单独的状态。我们将实现的第一个状态是探索状态,我们将其称为 AntStateExploring(参见清单 7-8)。此状态的条目操作为蚂蚁提供随机速度,并将其目的地设置为屏幕上的随机点。主要操作,在do_actions函数中,选择另一个随机目标,如果表达式

randint(1, 20) == 1 为真,这将在每 20 次调用中大约 1 次发生,因为 randint(在随机模块中)选择一个大于或等于第一个参数且小于或等于第二个参数的随机数。这给了我们正在寻找的蚂蚁般的随机搜索行为。

探索状态的两个传出链接在

检查条件功能。第一个条件查找距离蚂蚁位置100像素以内的叶子实体(因为这是我们的蚂蚁可以看到的距离)。如果附近有一个叶子,则check_conditions记录其id并返回字符串,这将指示状态机切换到搜索状态。其余

如果巢穴内和蚂蚁位置的100像素范围内有任何蜘蛛,则条件将切换到狩猎。

警告 随机数是使游戏更有趣的好方法,因为可预测的游戏可能会在一段时间后变得沉闷。但要小心随机数 - 如果出现问题,可能很难重现问题!

清单 7-8.蚂蚁的探索状态(蚂蚁状态探索)类蚂蚁状态探索(状态):

image.png

从清单 7-8 中可以看出,单个状态的代码不需要非常复杂,因为状态一起工作以产生超过其各部分之和的东西。其他状态类似于 AntStateExploring,因为它们根据该状态的目标选择一个目标,如果它们已完成该目标,或者它不再相关,则切换到另一个状态。

在游戏的主循环中,没有太多的事情要做。创建 World 对象后,我们只需调用进程并每帧渲染一次,即可更新和绘制模拟中的所有内容。在主循环中还有几行代码,用于在场景中的随机位置创建叶实体,偶尔创建从屏幕左侧游荡的蜘蛛实体。

清单 7-9 显示了整个模拟。当你运行它时,你会看到如图7-4所示的东西,蚂蚁在屏幕上漫游,收集树叶并杀死蜘蛛,它们会堆积在巢穴中。你可以看到蚂蚁满足成为AI的标准,因为它们在有限的意义上意识到自己的环境,并采取相应的行动。

您需要使用我们游戏对象库源代码中的 vector2.py 版本,或者您可以自己在此处编写一些新方法。这些方法可以执行诸如获取到给定点的距离或获取矢量的长度之类的操作。我鼓励您尝试自己构建它们,如果您发现自己卡住了,可以检查提供的源代码!

虽然这个模拟中没有玩家角色,但这是我们最接近真实游戏的一次。我们有一个世界,一个实体框架和人工智能。它可以通过添加玩家角色而变成游戏。你可以为玩家定义一个全新的实体,也许是一只必须吃掉蚂蚁的螳螂,或者为蜘蛛实体添加键盘控制,让它从巢穴中收集蛋。

或者,模拟是策略游戏的一个很好的起点,可以派出一群蚂蚁来收集树叶或突袭邻近的巢穴。游戏开发人员应该尽可能地富有想象力!

image.png

完整的 AI 模拟 代码分享

image.png image.png image.png image.png image.png image.png image.png image.png image.png image.png