游戏开发中的人工智能

前言

今天非常开心,观看cocos官方直播居然在几千人中中奖,可以买彩票了。 言归正传,所谓的人工智能,也就是大家常说的AI(Artificial Intelligence)。一说到AI可能就会让人觉得比较深奥,其实也就是非玩家角色思考和行为的综合。比如,在什么样的条件下,触发什么样的行为。 其实我们在游戏开发中的AI要比学术理论中的AI简单很多,甚至有些行为不需要AI也能体现。比如使用剧情对话体现非玩家角色的想法。 那么AI 都涉及到哪些东西呢?

  1. 控制器 我理解的控制器,就是非玩家角色的大脑,是用来思考事情的。例如通过执行决策树,得到一个有效的行为。使用不一样的控制器就会有不一样的思考方式。比如玩家的控制器就是根据按键操作触发不同的行为。阿猫,阿狗的可能又不一样了。
  2. 感知器 获得周围环境的情况,不如距离谁有多远,自身生命值多少,玩家生命值多少,等等。
  3. 反应 也就是控制器执行决策树后产生的有效行为。比如跳跃,跑,各种攻击,防御等等。
  4. 决策树 我理解为思考时的思路,比如应该在什么样的条件下执行什么样的反应。比如当我的血量低于百分之30的时候我要逃跑。具体案例体现在我的游戏《星际迷航》的第一个boss身上。
  5. 记忆 就是非玩家角色可以通过存储数据,供控制器执行的时候使用,以提高非玩家角色的智商。
  6. 学习 这个能力太牛逼了。实现起来也比较复杂,需要大量的数据和计算量为依托,而且在游戏开发中也并不一定实用。因此我也没用过。

如何应用到程序中呢?

  1. 首先还是要定义好行为枚举,通过状态机,不同的行为实现不同的逻辑。 image.png image.png

  2. 定义感知器特征 不同的游戏感知的特征肯定是不一样的,根据游戏需求而定 image.png

  3. 实现感知类 image.png

  4. 定义决策树

    export default class DecisionTree {
    
     private decisionData: XlsxData;
     private perception: Perception;
    
     constructor(data: XlsxData) {
         this.decisionData = data;
     }
    
     setPerception(perception: Perception) {
         this.perception = perception;
     }
    
     getPerception(obj, perceptionType: PerceptionType, value: number) {
         return this.perception.action(obj, perceptionType, value)
     }
     //开始思考
     action(obj: RoleView, decisionID: number) {
    
         let data = this.decisionData.getRowData(decisionID)
         let flag = false;
         if (data) {
             let perceptionType = data[Ai_dataEnum.condition];
             let type = 0;
             let id: number[] = null;
             flag = this.perception.action(obj, perceptionType, data[Ai_dataEnum.cParam])
             if (flag) {
                 type = data[Ai_dataEnum.conditionYes]
                 id = data[Ai_dataEnum.parm1]
             } else {
                 type = data[Ai_dataEnum.conditionNo]
                 id = data[Ai_dataEnum.parm2]
             }
             this.judge(obj, type, id)
         }else{
         }
         return flag;
     }
     //判定感知条件
     private judge(obj: RoleView, type: ThinkType, param: number[]) {
         if (type == ThinkType.ACTION) {
             this.doLogic(obj, param)
         } else {
             for (let index = 0; index < param.length; index++) {
                 const element = param[index];
                 if (this.action(obj, element)) {
                     break;//目前仅支持串行,不支持并行。如需支持并行,需要添加是否拦截字段。
                 }
             }
         }
     }
    
     // 50 30 20 : 80  根据概率选择行为
     private doLogic(obj: RoleView, param: number[]) {
         if (param.length > 0) {
             let r = RandomHelper.random(0, 100);
             let count = param.length / 2
             for (let index = 0; index < count; index++) {
                 let behaveType: number = param[index * 2]
                 let random: number = param[index * 2 + 1]
                 //
                 if (r <= random) {
                     // 设置非玩家角色的行为。
                     obj.setBehaveType(behaveType)
                     return;
                 }
             }
         }
    
    
}

}

5. 定义控制器

export default class EnemyController extends GameController {

private perception: Perception = new Perception();
private ai: DecisionTree;
constructor() {
    super()
    let ai_data: XlsxData = GameDataManager.instance().get(DataName.ai_data)
    this.ai = new DecisionTree(ai_data)
    this.ai.setPerception(this.perception)
}

getPerception(obj, perceptionType: PerceptionType, value: number) {
    return this.perception.action(obj, perceptionType, value)
}

action(obj: RoleView, decisionID: number) {
    this.ai.action(obj, decisionID)
}

}

6. 在非玩家角色中声明控制器和行为管理器
![image.png](https://img-blog.csdnimg.cn/20200701230636870.png)

7. 定义思考函数
think() {
    this.ai.action(this, this.model.getAI())
}

```

  1. 调用 image.png 在动作执行结束后,如果非玩家角色没有死亡,就会执行一次。然后再决策树中调用非玩家角色的设置行为的方法。 image.png 至此 ,就执行了一次AI的完整流程。从代码中我们可以看到,控制器是通过配置表数据执行操作的,接下来我们看配置表部分。

配置数据

image.png

  1. 首先数据表是二维的,我们要通过二维表模拟了树形结构。判定条件就是感知特征的枚举值,判定参数是留给感知器使用的参数,如果不需要可以不填,中文部分可以仅用于注释,并不会导出,判定条件成立或者不成立的时候都会用0和1来决定是继续判定还是处理行为选择。如果是0 后一列的数据会填写下一个节点的ID,也就是继续思考,如果是1,表示可以执行对应的处理。 此时,后边的列里边我是存放了行为枚举值和对应的概率。因为并不是所有行为都是百分之百执行的。将这个表导出之后提供给控制器使用就可以了。
  2. 数据表的索引方式 对于简单的ai,可以一个敌人对应一个决策树ID;对于复杂的AI,可以一个敌人的一个动作对应一个决策树AI。所以这里抛出了一个问题,就是手动填写这样的表,维护成本也比较高了,所以这里对于复杂的AI需求,建议自己开发个小工具,这样用起来不易出错,且容易维护。

结语

以上就是我个人对游戏开发中AI的理解,当然我是拜读了《游戏人工智能——计算机游戏中的人工智能》这本书的。好像此书已经绝版了。希望放出来对热衷于游戏开发的小伙伴们有所帮助。

长按下方二维码,关注《微笑游戏》公众号,获取更多精彩内容。

image

欢迎扫码关注公众号《微笑游戏》,浏览更多内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值