状态机--状态机5,关于战斗兵种的多状态

本文探讨了在游戏战斗中如何设计一个支持多状态的角色状态机,包括主状态和子状态的概念。主状态如待机、行走、攻击等互斥,而子状态如中毒、变羊等可叠加。状态机在切换状态时需要考虑子状态对主状态切换的影响,例如某些子状态可能阻止角色执行特定行为。通过这种方式,实现了角色状态的灵活管理和扩展。
摘要由CSDN通过智能技术生成

在前面一篇《状态机4,关于战斗中负责兵种状态切换的状态机》中实现了一个简单的状态机

在最后抛出了为什么说简单的问题,因为在一个复杂的战斗中,一个角色很少说只有一个状态,

或者说根本不可能,多状态是合理的需求,在之前实现的状态机中,角色同时只能有一个状态,

要么行走状态,要么冰冻状态,从代码逻辑上看,一个新的状态进来当前的状态会被顶替掉,


来看需求:一个角色的攻击的过程中中了一个中毒buff,在一段时间内会持续掉血,这种情况下

角色会同时有两个状态,攻击状态和中毒状态,中毒状态不会顶替攻击状态,在中毒状态下角色

也可以切换到行走状态,冰冻状态等等,那么从以上的需求来看,


我们可以把状态分为两种类型:主状态子状态

主状态:如待机状态,行走状态,攻击状态,冰冻状态等等,它们的特点是相互这间互斥,

角色在同一时刻只能处于其中一种状态,新的主状态进来会顶替当前的主状态

子状态:如中毒状态,变羊状态,隐身状态等等,它们的特点是相互之间独立,且不会顶替

掉主状态,如角色可以同时处于行走状态,中毒状态,隐身状态


经过上面的总结,我们把上一篇文章里提到的状态做下分类,并加入一些新的状态

主状态:待机状态,行走状态,攻击状态,冰冻状态,眩晕状态

子状态:中毒状态,网捕状态,变羊状态


总结完之后,大概说下新的状态机的原理,大部分跟之前的简单状态机一样,不同的地方在于切换

状态的时候,需要做一些额外的逻辑处理,

1.如果新进来的状态是子状态,那么直接新增一个子状态,并直接返回不做其他处理,

子状态可以独立添加和移除

2.如果新进来的状态是主状态,那么先检查一下角色身上的子状态,为什么要做检查,

下面说一下一些情况就能明白,

假如角色现在处于攻击状态,在此状态下中了一个网捕buff,网捕buff的作用是让角色

不能行走,带有网捕状态的角色只能呆在原地做攻击,待机等等行为,

再假如角色现在处于行走状态,在此状态下中了一个变羊的buff,变羊buff的作用是让角色

变成羊的模型,带有变羊状态的角色不能使用技能,不能攻击,其他如行走,冰冻是可以的


通过上面的例子可以总结出来,子状态的存在会影响到主状态的切换,那么我们的状态切换

规则就分三步:

1.如果新进来的状态是子状态,那么直接添加

2.如果新进来的状态是主状态,那么分下面几步:

如果是相同的状态,则直接返回

如果不是相同的状态,那么检查自身的子状态,是否有影响到主状态的切换的子状态

如果没有影响到主状态切换的子状态,那么检查是否有可切换的主状态


下面来看代码:

StateId.lua:状态id,没什么大的区别,只是新加了几个新的状态id,子状态从500开始,做区分

local StateId = {}

StateId.unKnown = -1
StateId.idle = 1 --待机
StateId.walk = 2 --行走
StateId.attack = 3 --攻击
StateId.frozen = 4 --冰冻
StateId.vertigo = 5 --眩晕

StateId.subStateStartId = 500 --子状态开始id
StateId.poisoning = 501 --中毒
StateId.netCatch = 502 --网捕
StateId.sheep = 503 --羊

StateId.name = {}
StateId.name[StateId.idle] = "待机状态"
StateId.name[StateId.walk] = "行走状态"
StateId.name[StateId.attack] = "攻击状态"
StateId.name[StateId.frozen] = "冰冻状态"
StateId.name[StateId.vertigo] = "眩晕状态"
StateId.name[StateId.poisoning] = "中毒状态"
StateId.name[StateId.netCatch] = "网捕状态"
StateId.name[StateId.sheep] = "羊状态"

return StateId


StateRuleConfig.lua:这个跟之前的有些区别,分为可切换的主状态和互斥的子状态

拿一个出来说一下,假设当前角色处于攻击状态(3)和网捕状态(502),要切换掉行走状态(2),

那么新进来的状态是主状态,要先判断是否有影响主状态切换的子状态,行走状态的id是2,那么取出

来的配置是:StateRuleConfig[2] = {majorStateCanToggle = {1, 3, 4, 5}, mutexSubState = {502}}

此时角色身上有网捕状态(502),在互斥配置中的相同的id,那么无法切换到行走状态


StateRuleConfig = {}

--状态id:待机状态(1),行走状态(2),攻击状态(3),冰冻状态(4),眩晕状态(5),中毒(501),网捕(502),羊(503)
--majorStateCanToggle:可切换的主状态
--mutexSubState:互斥子状态,

StateRuleConfig[1] = {majorStateCanToggle = {2, 3, 4, 5}, mutexSubState = {}}
StateRuleConfig[2] = {majorStateCanToggle = {1, 3, 4, 5}, mutexSubState = {502}}
StateRuleConfig[3] = {majorStateCanToggle = {1, 2, 4, 5}, mutexSubState = {503}}
StateRuleConfig[4] = {majorStateCanToggle = {1}, mutexSubState = {}}
StateRuleConfig[5] = {majorStateCanToggle = {1}, mutexSubState = {}}

retur
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值