本文转自 博客园 LOGOS ,转载请详细标明作者及出处,以示尊重!!
作者:LOGOS
原文:http://www.cppblog.com/darkdestiny/archive/2006/10/30/14400.html
自从看完PIL之后,就暂时没有时间做更多的尝试,也因此没有弄明白如何将AI脚本,剧情脚本之类的嵌入到C++的硬编码中。最近看了一些AI的文章,并思考了一下,得到以下认识。

首先要说的是,并不是说AI,剧情逻辑必须非脚本语言不可,用C++也可以写,甚至更习惯一些。但是脚本语言有脚本语言的长处,动态类型以及相当人性化的数据构造方式,特别是LUA中的表类型,似乎比较擅长描述这种复杂的AI/剧情结构。当然,为了验证自己的想法,我也写了4K的LUA代码,结果觉得该脚本语言相当不容易构造简洁的内容。

AI从高自低的分别是计划,状态机,模式。我不知道这种划分是基于何种角度,但是我个人的理解是状态机最高,模式作为某个状态下的某个决策所预定义的动作序列,而计划,是为了实现某个目标的一组步骤的组合。

那么硬编码的游戏循环何时调用脚本?答案是,游戏循环执行到调度NPC的AI函数的时候,该AI函数就不再做任何硬编码,而只是简单的dostring("gameEntitys[npc](\"update\")")。就是这么简单,将所有的AI/剧情放置到脚本中。

那么,LUA中 gameEntitys[npc]("update")是什么意思?简单的说,gameEntitys是一个存储所有NPC的注册表,gameEntitys[npc]将取得该npc的FMS函数,然后给该函数发送update消息告知npc当前的状态进行例行更新。
FMS函数对于每一个对象是唯一的,那么比如某一类对象有共同的AI/剧情,那么该类的每一个对象同用同样的FMS函数的话,成员变量如何维持?要知道在LUA中模拟类还是比较麻烦的。答案是upvalue,也就是所有的对象使用同样的函数来生成自身的FMS,该函数就是FMS_Creator(all_state, init_state)。

在C++编码中,NPC对象完成构造之后,就调用LUA载入对应的状态机/剧情脚本,然后调用FMS_Creator为自己创建FMS函数:

dofile("npc_ai.lua") --引入all_state,init_state
gameEntitys[npc]=FMS_Creator(all_state, init_state)

当然,NPC析构之后,你也要释放LUA为你分配的资源

gameEntitys[npc]=nil

已经大概说明了如何在C++中启动NPC的LUA逻辑代码了,那么如何在LUA中编写状态机呢?答案是表。每个表代表一个状态,该表下的key表示该状态接受的消息,key对应的值表示该状态接受到key所表示的消息后要执行的决策,包括相应的动作和可能的状态变迁。看代码吧,最直观的表述:

state = {
  name = "attack", --状态名
  enter = {  --进入该状态要执行,属于状态的消息
     --func是函数,param是参数,sucess,unsucess是func执行结果所对应的状态转移
    {func=print, param="open fire"},
    {func=IsEnemyDie, sucess="cure"},
  }
  update={}  --同enter,不过用于状态在每一帧的更新
  exit = {}  --同enter,不过用于状态在每一帧的更新
  other_msg = {}  --同enter,用于表示该状态所接受的其他消息,可以有多个
}

在LUA中就是可以如此直观的表示每一个状态,其响应的消息以及函数。然后构造该npc接受的状态集合:

all_state = {}
all_state[state.name]=state

init_state=state

这样子,就能传递到FMS_Creator中创建出自己独一无二的状态机函数了。

那么剧情脚本呢?其实描述了状态机,剧情脚本是否已经有点眉头了呢?剧情,即为计划,每一个计划由一系列步骤所组成。类似的,对应每个计划的执行会有一个plan()函数,且为了达到独立效果,该函数将会由plan_creator(all_step, first_step)生成。
看参数,显然计划的步骤step就是类似于状态的表,不过key方面略有不同,看代码就明白:

step = {
  name="find bill",
  cond = { --执行该步骤的前提条件
     --func是判断条件的函数,param是判断参数
     {func=IsXXX, param="xxx"},
    {func=IsStepFinished, param=some_step},
  },
  finish = {  --条件判断成功要执行的动作
    {func=print, param="success"},
  },
  unfinish = {  --条件判断不成功所要执行的动作
    {func=print, param="unsuccess"},
  },
}

至此,要说的基本上说完了。剧情与FMS结合的方式,因为个人认为FMS最高,所以剧情的执行通过plan(),该剧情的执行函数将作为某个状态相应某个消息时函数集合的一分子。因为,总有个状态是要求按计划执行剧情完成目标的,但是,其他状态允许意外使得暂时不能执行剧情,而NPC又不至于疯掉。

需要补充的是,很遗憾LUA不能随意的使用类似于#include,#import的功能,虽然可以dofile,但是其dofile内声明的变量必须是globle的,因为local value的生存范围是chunk,dofile就是在一个chunk内执行代码。

如何在游戏机制中使用AI/剧情脚本----基于LUA相关推荐

  1. 《游戏AI开发指南(基于Lua的人工智能在游戏中的应用)》(Yanlz+Unity+SteamVR+5G+AI+VR云游戏+Lua+人机交互+沙箱+导航+决策树+影响力地图+立钻哥哥+==)

    <游戏AI开发指南(基于Lua的人工智能在游戏中的应用)> <游戏AI开发指南(基于Lua的人工智能在游戏中的应用)> 版本 作者 参与者 完成日期 备注 YanlzAI_Lu ...

  2. AI技术在基于风险测试模式转型中的应用

    导读 基于风险驱动的交付是百度实践智能测试–感知智能阶段非常重要的研究方向,基于风险驱动的交付,源于三个现状: 一.不是所有的项目都有风险,80%以上的项目无任何的关联bug和线上问题: 二.不是所有 ...

  3. AI视觉组基于ESP32的裁判系统第一版本设计要求

    简 介: 面对第十六届全国大学生智能车竞赛中新增加的一些组别的要求,比如室内AI组,对于车模任务增加的检测任务,设计了基于ESP32为核心的比赛系统.本文给出了对于比赛系统功能的要求. 关键词: 比赛 ...

  4. 基于Lua脚本语言的嵌入式UART通信的实现

    随着变电站智能化程度的逐步提高,对温度.湿度等现场状态参量的采集需求也越来越多.就目前而言,在现场应用中,此类设备多采用RS232或RS485等UART串行通信方式和IED(Intelligent E ...

  5. Cocos2d-x 脚本语言Lua中的面向对象

    Cocos2d-x 脚本语言Lua中的面向对象 面向对象不是针对某一门语言,而是一种思想.在面向过程的语言也能够使用面向对象的思想来进行编程. 在Lua中,并没有面向对象的概念存在,没有类的定义和子类 ...

  6. lua软件测试自动化,一种基于Lua脚本的嵌入式软件自动化测试系统及方法专利_专利查询 - 天眼查...

    1.一种基于Lua脚本的嵌入式软件自动化测试系统,其特征在于,所述系统包括:目标 测试系统及测试主控系统,其中: 目标测试系统包括: 标准化的软件接口 :用于与被测对象进行数据交换: Lua解析器:用 ...

  7. lua脚本之lua语言简介以及lua的安装

    本博主不擅于进行文字创作,所以,相当一部分文字皆复制于其他博文.还希望能够得到谅解.  一.Lua语言简介 Lua是一个免费的开源软件,可以免费用于科研及商业.Lua具有一个专家团队在维护和升级,其设 ...

  8. js弹幕脚本(基于油猴)

    js弹幕脚本(基于油猴) 该脚本包含往视频上插入弹幕,发射弹幕,弹幕查询,弹幕暂停,脏话过滤等基础功能.话不多说 ,直接上代码. 仅供参考 ,该代码是我给别人写的定制化的,复制后不可用. // ==U ...

  9. 深度学习aec数据前处理脚本,基于timit和汪德亮老师的paper

    该脚本基于 Deep Learning for Acoustic Echo Cancellation in Noisy and Double-TalkScenarios 中汪德亮老师学生中对timit ...

最新文章

  1. 在线协作沟通,以目标分解成任务树基础的团队配合
  2. linux进程间通信之Posix共享内存用法详解及代码举例
  3. 【NLP】Prompt-Tuning这么好用?
  4. mysql delete in死锁_mysql 执行delete引发死锁问题
  5. 我的Java设计模式-原型模式
  6. 前端学习(3054):vue+element今日头条管理-状态展示处理
  7. 用python计算列表元素之和_python实现计算列表元素之和
  8. 中文车牌识别开源项目C++版使用笔记
  9. VS 下环境覆盖率测试
  10. 上海电信路由器有ipv6,电脑无法获取ipv6问题记录
  11. 慧荣SMI_量产图文教程
  12. 计算机网络【IP协议与以太网】
  13. sparkstreaming的实时黑名单过滤太慢
  14. 量子力学在计算机上的应用论文,《浅谈量子力学的发展与利用》-毕业论文.docx...
  15. R语言基础统计分析:正态性检验、方差齐性检验、T检验、方差分析、秩和检验
  16. 【华为报考全攻略】华为考试自己如何报考?
  17. Linux下GL850G调试总结
  18. Windows10神州网信版的安装
  19. 5-10 公路村村通 (Kruskal+并查集)
  20. 知识图谱—语义网络、语义网、链接数据、知识图谱

热门文章

  1. L1-014 简单题 (5 分)
  2. mysql之查询某段时间范围的数据
  3. 模块化无人机,不仅配置高,还颜值爆表
  4. LindDotNetCore~入门基础
  5. Saltstack远程执行命令(3)
  6. centos7.2安装五笔输入法的方法(king已测)
  7. android dialog的封装,Android系统Dialog的简单封装
  8. php伪协议漏洞_php伪协议利用文件包含漏洞
  9. python程序的扩展名是perl程序的扩展名是_Python 程序扩展名(py, pyc, pyw, pyo, pyd)及发布程序时的选择...
  10. 个人作品- 蘑菇大战