使用行动列表去创造简单且可扩展的游戏AI
作为人类,我们似乎总倾向于使用自己所熟悉的解决方法。我们总是会按照我们所知道的方式去做某些事,而不是按照做这些事的“最佳”方式。因为总是带着这种想法,所以我们很容易使用一些过时的技术,并使用那些同时代人所不理解,或者并不是那么有效的方式去执行特定功能。所以我希望通过本文以及之后的文章向广大读者们介绍更多能够在编程中带给你们帮助的解决方法。今天我要分享的便是行动列表!
行动列表是所有游戏开发者都必须清楚的简单但却强大的AI。尽管不能与巨大的AI网络相匹敌,但是它们允许相对复杂的突发行为,并且执行起来也很简单。不管你是刚刚接触AI编程还是着眼于扩展工具包的资深开发者,本文都将向你详细介绍行动列表并提供一些有效的例子帮助你更好地执行解决方法。让我们开始吧。
从前
几年前我开始开发《King Randall’s Party》,在游戏中玩家将建造城堡并为了保卫它与尝试着摧毁它的King战斗。我需要创造一个能够瞄准玩家城堡并计划如何去摧毁它以达到自己目的的机智的AI。这对我来说是个巨大的挑战,因为目标太大我很难同时顾及全面。所以就像任何其他优秀的程序员那样,我将其分解成一个比较容易管理的问题集。这时候我所面临的第一个挑战便是:我需要创造一个拥有特定行为集的单位。
而快速的网络搜索让我的精神差点崩溃。只要搜索“游戏AI”便会出现有关策划者,有限状态机,指导行为,向导等等结果。我根本不知道该从哪里开始,所以我只能做任何理性的人会做的事。对的,我询问了我们家的狗。当然了,对于我来说这并不是什么新鲜事了。不管什么时候当我遭遇技术问题时我都会去询问我们家的狗。这时候你可能会想:“Jesse,你太疯狂了吧。狗怎么可能了解计算机?!”好吧,让我们先不要管这个。也许这里包含或并未包含某种非法技术或者出现在大学审计课堂中的内容。
不管怎样我会说:“好吧Frankie,我知道对于AI我们有许多事要做,但是我并不清楚该从哪里开始。我该如何为我的游戏单位创造一个AI框架?”Frankie的表情让我觉得自己就是个愚蠢的人,尽管我的高中老师Francis先生已经告诉我不要提出任何愚蠢的问题。我非常肯定Frankie并未想到Francis先生。她反问我:“Jesse,通常你是如何开始你的一天的?”
我会把我一天需要做的所有事列下来然后根据这些任务的重要性以及所需时间对其进行排序。我这么回答Frankie然后她说道:“这便是行动列表。”她告诉我行动列表是关于你的游戏单位在特定时间内运行的任务或行为列表。这是一种有限状态系统形式,并且能够被描述为是带有一个分支的简单行为树。以下便是关于它们是如何运行的。
行动列表如何运行
首先你将写下你希望你的AI所拥有的所有行为。
然后你需要对它们进行先后排序。从最低到最高。
现在我们需要迭代该列表去检查每个行动是否能够有效执行。然后我们将检查行动的粘附性能,如果某个项目会阻碍之后的行动,我们便会退出该列表。之后我们便会清楚为什么这种阻碍如此重要了。
在我们的例子中,我们的第一个行动“攻击玩家”将只在AI靠近玩家的时候执行。买手机游戏让我们假设它并未靠近玩家,所以它将检查是否能在当前位置上创造一个阶梯等,直至它找到一个能够执行的行动条款,如打破门。然后它将执行破门代码。
“阻碍”便是在这里开始发挥作用。如果破门马上发生,它便不会阻碍到任何之后的行动,而之后的列表内容便可以继续执行。但通常情况都不会如此—-行动总是占据一个以上的帧数。所以在这种情况下破门行动项目将调用unit.Attack(door),即将单位的当前状态从等待改成破门,而在门被打破之前将恢复到true的状态。
一个简单的有限状态机
这听起来好像是可行的。Frankie提供了一个很好的建议,行动列表似乎也非常适合我的项目。但在此之前我却从未听过它们,所以我对此还是充满疑问—-我听到的大多数关于AI的内容都必须使用基于转变的有限状态机,即类似于在MUnity3D用于创造动画所使用的工具。你将定义一些状态并识别它们何时以及如何彼此转变。Frankie向我我解释了当你在创造一个基于转变的有限状态机时,你需要定义你想要拥有的所有状态,然后你也要定义这些个体状态间的所有转变。这真的会让内容很快变得复杂。如果你拥有一个“伤害”的状态,你便需要识别其它能够转变成这个状态的状态。如走路变成伤害,跳跃变成伤害,蹲伏变成伤害,攻击变成伤害等等。这是很有用的方法,但却很快便会变得复杂。如果你的AI需求非常简单的话,这可能会是一笔潜在的不必要开支。
关于基于转变的状态机的另一个难点便是调试。当你设置了一个停止点并着眼于AI当前的状态,这时候如果没有额外的调试代码,你便不可能了解AI是如何进入当前的状态,它之前的状态是什么以及怎样的转变将它带到现在的状态。
行动列表的缺陷
当我进一步深入行动列表时,我意识到它们非常适合我的执行内容,但同时我也发现它们存在一些缺陷。最大的缺陷便源自其最大的优点—-简单性。因为这是一个有序列表,所以我不可能拥有任何复杂的优先顺序结构。所以如果我希望“攻击玩家”排在“破门”前面,但却在“移向目标”后面,但同时我又希望“移向目标”出现在“破门”后面,我便很难使用行动列表做到这点,而用有限状态机的话又会非常繁琐。
总而言之,行动列表对于简单的AI系统真的很有帮助,但是如果你想创建的是较为复杂的AI,那么执行行动列表便会较困难。也就是说你可以通过某些方法去扩展行动列表概念而将它们变得更有帮助。
扩展这一概念的方法
我的一些AI单位需要完成多种任务—-它们可能需要同时移动并发动攻击。我可以创造多个行动列表(注:一个处理移动,一个处理攻击),但这么做也存在问题,即如果有些移动类型会妨碍攻击,而有些攻击又需要单位站在原地的话该怎么办?这时候行动线路(Action Lanes)便会发挥作用。
行动线路是对于“阻碍”概念的扩展。基于行动线路,行动项目便能够识别阻碍执行的特定行动项目类型并允许其它项目顺畅地执行任务。让我们进一步展示这一执行。
行动线路只是决定行动的一种附加方法。每个行动项目都属于一条或多条线路,当阻碍性能变成true时,它将添加所属的线路,因为每个行动都拥有一条或多条线路,所以它们只是阻碍其它属于这些线路的行动。举个例子来说吧,因为单位在创造阶梯时必须保持不动且不能发动攻击,所以攻击玩家属于行动线路,移向目标属于移动线路,创造截图同时属于这两种线路。然后我们将排列这些项目的顺序,如果它们同时执行便会阻碍到后续的行动。
执行案例
现在我们已经了解了这一理论,所以我们可以尝试一次真正的执行过程。首先让我们设置行动列表和行动项目。对于行动项目我希望能够分离执行,所以让我们创造一个接口。
以下便是BreakDoor行动项目的IActionItem执行:
对于行动列表本身我可以使用一个简单的列表。然后我们将使用IActionItems去加载它。
之后我们将设置一个方法并在每帧中迭代列表。需要记得我们同样也需要处理阻碍。
如果你想要使用行动线路的话事情会变得更复杂。这时候我们将把行动线路定义为位字段然后修改IActionItem界面。
然后我们将为这些线路修改迭代程序。如果行动项目的线路遭遇阻碍,它们便会被略过,但检查的时候仍是正常的。如果所有线路都遭到阻碍,我们便会改变这一循环。
结论
可以看出需要理解的内容有很多。Frankie让我总结从中学到的内容,于是我经过综合思考得出了一些关键要点。
行动列表比小型基于转变的状态系统更容易创建与维护。
它们创造了一个可识别的优先系统。
存在一些扩展方法去处理扩展功能。
在编程中我们很难找到最佳解决方法。所以我们必须确保我们的工具箱中拥有各种编程工具,如此我们便可以及时选择一个能够有效解决问题的合适工具。最终证明行动列表非常适合《King Randall’s Party》。而它是否也同样适合你们的项目呢?
使用行动列表去创造简单且可扩展的游戏AI相关推荐
- 开机不进去桌面执行gui_电脑系统崩溃进不去,简单几步设置U盘,快速找回桌面重要文件...
hello~我可爱的粉丝们!今天粮小白分享一个电脑系统崩溃无法开机,怎么把电脑数据保存备份的小技能,就来就点个关注吧.每天更新生活必备技能哦. 电脑系统崩溃进不去,简单几步设置U盘,快速找回桌面重要文 ...
- python输入一组数字存到列表_Python如何使用输入传递多个值并将它们存储在一个列表中(简单版本),python,怎么,input,传入,储存,到...
Python如何使用输入传递多个值并将它们存储在一个列表中(简单版本),python,怎么,input,传入,储存,到 发表时间:2020-08-20 当传入多个值时,需要使用split()函数来切割 ...
- 了解ACL(访问控制列表)一些简单的ACL小实验
了解ACL(访问控制列表)一些简单的ACL小实验 一.访问控制列表(ACL) 1.1ACL工作原理 1.2ACL的两种作用 1.3访问控制列表在接口应用的方向 二.访问控制列表的处理过程 三.ACL的 ...
- python去重复记录_Python列表去重复项的N种方法(实例代码)
说明 Python语言中列表(List)与其他语言的数组(Array)类似,是一种有序的集合数据结构,Python List可支持各种数据类型,长度也可动态调整,与JS中的数组或Java ArrayL ...
- 如果没有,那么就去创造
上周末在回北京的路上,看到一个广告牌,上面有一句:"如果没有,那么就去创造". 是啊,自己的生活只能靠自己创造,从无到有. 转载于:https://www.cnblogs.com/ ...
- 《富人的逻辑》书中的精髓:为什么暴富起来的人会在短期内失去财富,我们又该如何去创造财富和持续拥有财富。
<富人的逻辑>书中的精髓:为什么暴富起来的人会在短期内失去财富,我们又该如何去创造财富和持续拥有财富. "等我有钱了,我可以让身边的亲人过上更好的生活:等我有钱了,我想买什么就买 ...
- 【数学/多项式】用列表去实现一元多项式函数的四则运算,和它的n阶导数的Python算法实现
目录 一元多项式函数 一元多项式函数的N阶导数 一元多项式函数的加减法 一元多项式函数的乘法 完全代码 运行结果 一元多项式函数 所谓一元多项式函数就是形如: 其中,,满足这样的形式的函数我们就称其为 ...
- 基于列表框的简单选课窗体开发。编写Windows应用程序,设计实现一个简单选课系统,要求:(1)点击“添加”按钮,将把在第一文本框中的输入的课程名称添加到左边的列表框中,且所添加的课程不能为空,不能
基于列表框的简单选课窗体开发.编写Windows应用程序,设计实现一个简单选课系统,要求: (1)点击"添加"按钮,将把在第一文本框中的输入的课程名称添加到左边的列表框中,且所添加 ...
- 使用ps去快速简单修改图像分辨率DPI为300并不改变原图尺寸大小的方法
使用ps去快速简单修改图像分辨率DPI为300并不改变原图尺寸大小的方法分享_哔哩哔哩_bilibili
最新文章
- Cobbler 2.4.4 安装
- 利用python编写设计多线程web服务器(计算机网络_自顶向下第六版_第二章1和4的编程作业)
- boost::coroutine模块实现相同的边缘的测试程序
- Spring+ Spring cloud + SSO单点登录应用认证
- ABAP Netweaver和SAP Hybris的内存管理
- Oracle的where子句
- 如何在 Web 开发中找到第一份工作?
- 台式电脑如何重装系统windows10
- SQlite数据库的C编程接口(五) 便捷函数(Convenience Functions) ——《Using SQlite》读书笔记
- 以项目管理的理念制作高质量的标书
- 组态王总结之——数据库功能
- Android APP打开另一个APP完整逻辑实现
- 2022年各国程序员薪资排名!
- 不小心删除电脑系统所有字体的解决方法
- 成功,侥幸,以小博大?永远离不开的墨菲定律
- Vue Typescript @Prop
- 202302|读书笔记——国图点滴
- 腾讯兔小巢是什么?零代码如何连接企业微信机器人
- 原生javascript的账号密码登录验证
- zynq+linux+ramdisk can调试
热门文章
- sql输出带颜色的字段_带你走进MySQL数据库(MySQL入门详细总结一)
- windows href 可以设置header吗_windows电脑端有什么桌面办公便签可以设置农历时间提醒?...
- CRK计算机,crk_world
- 深度学习总结:GAN,原理,算法描述,pytoch实现
- kubeadm单集群部署k8s1.15.1flannel网络
- Linux中常用的查找文件的命令
- 设置storage模块的数据库操作支持、添加仓储分类列表接口(dao层)
- 利用委托 实现窗体间通信,非原创
- sql xml 入门
- 手机客户端测试点(全)