客户端ARPG角色行为模型

[概述]

  对于玩家自身而言, 场景中的角色分两种:自己,别的生物(包括别的玩家,monster, npc等)。而生物本身是一个集合{属性数据(状态), 行为(动作表现)}。

  站在玩家自身的角度来看, 对于别的生物, 他们的所有数据和行为都是来自服务器, 客户端要做的相当于播放录像的功能, 根据服务器送过来的指令对他们进行控制和表现。

  而玩家自身, 其行为来自两个地方:1、操作模块(比如说客户端的io操作, 程序发出的操作指令等, 操作模块内部封装了所有的操作指令, 对玩家对象进行控制), 2、服务器指令。操作模块的指令会向两个路径分发:1、向服务器发送请求,2、向玩家自身发送指令.
 

[角色行为]

和角色行为相关的变量:

1、  完成条件(即条件满足前不能进行其他行为)。

2、  位置(产生行为的角色位置)。

3、  方向。

4、  状态(此行为对应的角色状态)。

5、  动作表现。

 

[行为分类]

1、walk.  终点位置, 速度

2、run. 终点位置, 速度

3、攻击(施法). 位置,方向

4、受伤(被攻击).

5、死亡. 位置

6、冲撞、被冲撞、死亡击飞等运动轨迹相关. 终点位置       

[玩家自身]

[一] 连续移动

1、客户端角色Me每预先跑一步A-->B, 都要等待服务器的返回(失败或者成功)。在服务器返回响应之前(Me有可能在移动过程中, 也有可能已经到达B点等候),客户端有可能存在以下操作:

         a、移动操作, 即点击场景其他地方C(即玩家想下一步移动到C),此时应该把C立即加入到移动队列中。

                   如果服务器返回成功, 则继续处理移动队列;如果服务器返回失败, 则将Me拉回到A点, 并清空移动队列。

         b、其他操作(如攻击)

                   如果服务器返回成功, 则清空移动队列, 并处理操作队列;如果服务器返回失败, 则将Me拉回到A点, 并清空移动队列, 操作队列。

        

[二] 攻击

客户端角色Me的位置CP, 服务器位置SP

1、CP与SP位置一致, 则立即发送attack指令到服务器, 并立即切换到attack状态,表现攻击动作。

2、CP与SP位置不一致(有可能正在移动过程中, 即已经发送move指令到服务器), 则立即发送attack指令到服务器(预先攻击)

         a、如果attack指令返回成功, 则等待CP与SP相同时则前端进行攻击行为流程。

         b、如果attack指令返回失败, 则清除标志, 并等待下一步操作。

 

3、尝试释放技能的时机

  a、任务开始时在当前位置判断能否释放。

  (有可能攻击失败, 因为玩家位置已变, 延时通知)

  b、开始一次新的移动,先向服务请求移动,前端预移动,并且判断能否释放, 如果可以则预释放。服务器返回移动请求和释放请求成功后,等到达目的点之后表现攻击动作和特效,否则清除预攻击状态。

  (有可能攻击失败, 因为玩家位置已变, 延时通知。这时候是否需要根据当前玩家移动的时间做一个判断策略?一次移动的时间间隔是560ms, 正常的网络传输延时极限(玩家移动广播到达之前+自己发送攻击请求到服务器延时)3个传输延时和2个服务器处理延时)。

  c、收到攻击对象位置变化广播时,判断能否释放,如果可以, 则根据自己当前的状态进行释放或者预释放。

  (这个时候成功率最高, 因为玩家位置延时最短。)

  以上三个时机形成了开始一个攻击任务整个阶段的闭环。

[其它场景对象]

这里的处理模型, 主要用于处理行为队列中存在多个行为的情况(大部分原因是网络延迟引起的)

[一] 移动

1、  行为队列全部是移动行为, 两种处理方式:

a、  依次处理每个移动行为。

b、  根据队列长度,直接处理队尾的移动行为,并清空行为队列。

2、  行为队列最后一个行为是攻击行为, 同样是两种处理方式:

a、  依次处理每个移动行为。

b、根据队列长度,直接处理队尾的攻击行为,并清空行为队列。

 

[二] 攻击

处理模型同上。

 

[三] 服务器强制同步行为

服务器有时候会强制同步行为, 如瞬移等。 则立即清空行为队列, 并执行强制同步行为。

 [操作模块]

操作模块是针对玩家自身的操作(io操作、自动挂机产生的操作等),将其转换为控制玩家对象的一个逻辑控制任务, 这里用operation表示,比如移动、释放技能、访问npc等都可称之为operation。

1、创建一个operation之前, 要先判断能否创建这个operation,不能则不响应玩家操作;若能, 则创建一个operation,并且插入到operation队列中。

  例如玩家当前处于摆摊或则死亡等不能移动的状态, 如果这时候玩家操作想移动, 则直接返回不响应。

  例如技能cd没到或魔法值不够等处于不能释放技能的状态, 如果这时候玩家操作想释放技能, 则直接返回不响应。

2、若当前正在执行的operation失败, 则要判断失败原因, 判断是否要重新尝试。

  例如移动任务,在移动过程中遇到阻挡点或则服务器返回移动失败, 则重新寻路。寻路成功,则继续执行;失败,则放弃任务。

  例如释放技能(有可能会创建一个移动的子任务),在执行过程中发现魔法值不足等问题, 则直接放弃任务。若是移动失败,则尝试重新寻路。

  

[行为队列模式(FIFO)]

无论是某个具体的动作行为,还是某个改变状态的操作, 都可以抽象为一个action cmd。

每个entity持有一个ActionModel, 每个ActionModel维护一个action list。

 

[一]实现细节

1、因为要频繁产生action cmd, 如何防止碎片化问题, 在解决这个问题的时候, 不能影响可维护性和扩展性, 尤其是扩展性。

2、action list: a1 a2 a3, 在表现上, 由于a2是一个持续性过程, a3有可能会影响a2的表现, 也就是a3可以在a2的执行过程中直接处理, 从而达到并发性表现(并发性的cmd可以使得表现更为丰富)。据此可以抽象, action cmd可以分为:互斥性action和并发性action。

action list的处理流程:

         if(curAction.isEnd)
         {
             curAction = list.empty ? action_idle : list.pop_front;
         }

         while(!list.front.isMutex(curAction))
         {
             Process(list.pop_front);
         }

         curAction.update;

 

 

[事件与状态]

1、移动

{run, walk} --> {move}

failed:

拉回原地

2、攻击

{物理攻击} --> {物理攻击状态}

{魔法攻击} --> {魔法攻击状态}

failed:

只播放攻击动作, 不播放后续的特效

3、冲撞

{rush} --> {冲撞状态}

{rushed} --> {被冲撞状态}

 4、受伤

{beHit} --> {hurt}

5、死亡

{die} --> {死亡状态}

6、采集

{gatherItem} --> {采集状态}

实时战斗系统问题锦集

1、人物动作处理策略
    由于某个原因(网络延迟等), 当前正在处理的动作尚未结束(比如移动尚未到达目的地), 此时又收到另外一个要处理的动作协议,这时候的处理策略。
    a、直接将人物状态设置到当前动作的目标状态, 然后开始新的动作。
    b、按正常流程处理当前动作, 并且把要处理的动作入队, 待当前动作完成, 再依次处理动作队列里的内容。
    
    问题衍生:如果把问题放大化, 即当前动作尚未结束, 后面收到一串待处理的动作, 此时的处理策略。

    有可能出现的情况:
    a、正在移动, 网络送来攻击行为        -->位置不一致
    b、正在攻击, 网络送来移动行为        -->位置不一致
    c、正在攻击, 网络送来新的攻击行为    -->表现不一致
    
    处理原则:优先保证位置一致,其次保证表现上的一致性。
    
    处理策略(实际上这里的动作处理, 仅仅是影响人物的表现, 还有坐标位置):
    动作按处理的紧急:
    <1>可以延迟处理的,放入队列缓存
    <2>需要立即处理的(如冲撞, 不立即处理的话,冲撞和被冲撞的表现不一致了。如怪物正在攻击(表现攻击动作))
    
2、技能释放的处理策略
技能分类:
    按技能的释放方式:主动、被动
    按攻击目标的数量:群攻、单体
    按是否需要目标:需要、不需要
    按是否魔法锁定:锁定、不锁定
    按施法距离:近身、远程
    按作用目标:只能对自己、只能对队友、只能对敌人
    
技能释放的前提条件:
    cd、距离、魔法量、目标

技能释放的要素:
    释放人、目标、方向、 目标点
    <1>从当前位置释放,作用于目标(或目标点)(要判断施法距离)
    <2>在当前位置朝当前方向释放技能(战士技能)
    <3>在当前位置朝鼠标方向释放技能(shift+左键攻击或者两个比较特殊的技能(地狱冰封,极光电影))
    <4>施加于自身(可以合并到<1>, 只是不用判断施法距离)
    
    特殊案例:
    群体治疗术、群体隐身术(作用于当前鼠标位置)
    单体治疗术、单体隐身术(作用于当前鼠标所在的目标, 如果没有目标,作用于自身)
    
3、打击感的体现

4、鼠标和键盘按着不放进行操作的延时机制
如果按着鼠标或者键盘不放,一秒钟可以触发次数:
鼠标:由程序主线程控制, window系统不会主动触发
键盘:34次/s

如果窗口样式指定了CS_DBLCLKS, 则双击鼠标产生的事件:

down->up->double click->up
否则:

down->up->down->up,此时需要使用者根据一定的规则自己检测并生成双击事件。

转载于:https://www.cnblogs.com/zilongblog/p/4184793.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值