欢迎来到天天文库
浏览记录
ID:42997511
大小:383.01 KB
页数:6页
时间:2019-09-24
《怪物AI模块结构》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、怪物AI模块结构概述本文档描述了一种新的怪物AI结构(架构),并相应阐述了该结构相对于目前的AI结构而言,可能面临的问题及其解决方法。现有AI结构的问题怪物AI本质上就是对AI的各种具体状态的驱动。现有AI模块在以下几个方面存在问题:1)状态转换、状态层次没有划分清楚,导致模块结构不够清晰(很多地方存在特殊判断);2)状态切换的逻辑处理模糊,如从战斗状态转换为和平状态的逻辑代码位置放置不合理导致的BUG。新AI结构的设计思想本文档描述的AI结构,在结构上硬性地将各个状态明确地区分出来,以求在整体结构上取得清晰。本质上,就是将各个AI状态拆分成单独的逻辑功
2、能类,如下图:图1将AI逻辑功能拆分出来其中,AI类本身不再包含具体的状态处理逻辑代码,而是把这部分代码拆分到具体的状态类里。AI的状态转换,也需要建立准确的实现机制。状态的基础设计一个状态,包含了以下几个重要的接口:virtualvoidreceive(void*cond){}virtualvoidenter(entity_type*){}virtualvoidleave(entity_type*){}virtualvoidexecute(entity_type*)=0;其中,receive函数表示由外部输入转换条件(详细参看有限状态机相关论文解释),
3、该函数通常可用于外部模块传入参数。例如,在怪物受到技能伤害时,在原有AI结构中会调用WhenBeenHurted函数,具体的AI类需要保存该函数参数指定的攻击者GUID。在此处,receive函数可用于实现此功能。enter函数用于处理状态转换之初需要执行的处理,例如刚从和平状态转换到战斗状态时,战斗状态需要做些初始逻辑处理。leave函数用于处理离开该状态时的逻辑。execute函数用于处于该状态时需要做的处理。通过强行划分以上几个状态转换步骤,希望可以将状态转换所需要的各种逻辑规划清楚。具体的状态机实现参看附件kl_state.h。具体结构具体的结构
4、如下图:图2AI整体结构其中,StateMachine仅仅是封装State切换时需要执行的状态过渡代码,包括老状态的leave、新状态的enter操作。该结构存在两个设计要点:1)将各个状态的逻辑处理拆分到不同的状态类中,这个之前有所描述;2)通过组合不同的状态实现,可以形成不同的AI类型。例如,怪物AI都有和平状态,但是我们可以实现被动怪和平状态(PeaceStateA)、主动怪和平状态(PeaceStateB)AIController通过配置具体地选择是使用PeaceStateA还是PeaceStateB,与其他不同的状态实现组合,即可组合出新的AI
5、类型。AIController的Init接口大致可实现为:structAIConfig{intHangupType;intFightType;intPeaceType;///morestatetype};boolAIController::Init(constAIConfig&cfg){m_pHangupState=CreateHangupState(cfg.HangupType);m_pFightState=CreateFightState(cfg.FightType);m_pPeaceState=CreateFightState(cfg.PeaceT
6、ype);//morem_pStateMachine=newStateMachine(this);//initialstatem_pStateMachine->change(m_pHangupState);returntrue;}更多实现参看附件AIController.h。与外部模块的交互状态的转换分为内部转换和外部请求转换。这里的外部/内部是相对于模块内外而言。例如在怪物和平状态运行(execute)期间,若检测到周围有敌人,则自发地转换为战斗状态,这是内部转换;在怪物受到技能伤害时,怪物也需要转换为战斗状态,这是外部转换
7、。内部转换由状态本身的逻辑代码决定,不存在问题。外部转换则需要做一些处理:AIController在某个角度上,是沟通各个状态和怪物之间桥梁,同时也是AI模块对外部模块的交互界面(interface)。也就是说,技能模块在与AI模块交互时,也会如现有AI结构一样调用诸如WhenBeenHurted的函数。在此结构中,AIController大致会做如下的处理:voidAIController::OnHurted(longtype,constCGUID&Id,longhurt){m_pMachine->cur_state()->receive(PtrPar
8、am(COND_HURT,type,Id,hurt));}假设当前状态是和平状态
此文档下载收益归作者所有