场景中的角色 大体上分为2种:
玩家自己、别的其他的(别的玩家、怪物、NPC等)
对于玩家自己而言,别的物体他们所有的数据和行为都是服务器告知的,别的玩家的数据和行为是别的客户端上报的,怪物和NPC的是服务器下发的,客户端只需要解析这些数据然后做相应的回应就好。。。
玩家自身的行为来自2个地方:操作模块和服务器指令
操作模块:操作模块内部封装的所有操作指令对玩家对象进行控制,说白了就是UI控件-->发出不同的指令---->玩家不同的表现
服务器指令:操作模块发出的指令会向2个路劲分发 a:向服务器发 b:向玩家自己发送指令
角色行为:
行为分类:
walk 终点位置、跑的速度
run 终点位置 移动速度
攻击或者释放技能 位置、方向
被攻击(伤害)
死亡 位置
冲撞、被冲撞等 终点位置
玩家自身:
玩家连续移动:A------->B-------->C------->D
客户端角色采用的是预先移动机制,就是说先跑一步比如说A---->B顺便告诉服务器 我要去B了,如果在服务器返回响应之前(客户端有可能还在移动之中,也有可能已经到了B),客户端有可能存在以下操作:
a:移动操作,点击位置C,玩家想去C点,此时就要把C加入到移动队列中。如果此时服务器返回成功,也就是到B点这个事件是成功的,那就接着处理移动队列里边的事件(去C),如果服务器返回失败,那么就要把玩家位置从当前位置拉回到A点,同时移动队列里边的数据清理掉。。。。
b:其他操作 比如攻击 (A--->B的过程中或者是到B之后,发出攻击指令。。。)
如果服务器返回成功,清空移动队列,开始处理操作队列。如果服务器返回失败,那么就跟上边一样拉回到A点,清空移动队列、操作队列。
玩家攻击:
客户端角色的位置a 服务器位置b
1:如果a和b位置一致,那么立即发送attack指令到服务器,并且切换到attack状态,表现攻击动作。
2:如果a和b位置不一致,可能就是正在移动过程中,已经发了move指令到服务器了,这个时候立即发送attack指令到服务器(预先攻击)。如果攻击返回成功,则客户端等待a和b位置相同时,进行攻击行为流程。如果攻击返回失败,那么就要清除标记,就当做没有发出攻击指令,等待下一步操作。。
3:尝试释放技能的时机
任务开始时在当前位置判断能否释放,有可能攻击失败因为玩家位置变化、延迟通知
开始一次新的移动时,c-->s发出请求移动,c预先移动并且判断能否释放技能,如果可以那就先释放并且告诉服务器,等待服务器返回移动请求和释放技能请求成功后,等待达到目的地之后表现攻击动作和特效,否则的话就要清除预攻击状态。。。
收到服务器发的 攻击对象位置变化广播时,判断能否释放技能,如果可以,那么就根据自己当前的状态进行释放或者预先释放。。。。
其他场景对象
移动:行为队列全部都是移动行为 要么一个一个都处理了,要么只处理最后一个 然后清空行为队列
行为队列最后一个是攻击行为 要么一个一个处理,要么只处理最后一个 然后清空行为队列
攻击:跟上边一样
服务器会强制同步行为,立即清空行为队列,强制按照服务器数据来展示行为。。。
操作模块
这个主要是通过UI控件 来操作的,针对玩家自身的操作,移动、释放技能、访问npc都是一个操作
创建一个操作前判断一下。比如说玩家处于死亡等不能移动的状态,这个时候玩家想执行移动操作就没有必要响应了。技能cd没有到或者魔法值不足等处于不能释放技能的状态,这个时候玩家想释放技能,则直接不响应就好了
如果当前执行的操作失败了,要判断一下失败的原因,看看是否有必要重新尝试一下。比如移动人物,移动过程中遇到了阻挡点或者服务器返回移动失败了,尝试重新寻路。寻路成功继续移动,失败的话就直接放弃。。比如释放技能(包含一个移动的子任务),如果是魔法值不足直接放弃,如果是寻路问题可以再次尝试重新寻路然后再继续。。。
行为队列FIFO
每个entity会有一个action list,动作行为或者动作改变都可以是一个action cmd。
行动序列最简单的就是互斥性的,一个cmd执行完了才能执行下一个cmd,但是也有些action cmd可以并发性表现,并发性的cmd可以使得表现更为丰富。。比如说action list:a1 a2 a3,表现上a2 是一个持续性的过程,a3有可能影响a2,也就是a3可以在a2执行的过程中直接处理,也就是并发执行。。。。
事件状态
run,walk---->move 失败了拉回原地
物理攻击----> 物理攻击状态 魔法攻击---->魔法攻击状态 失败了只播放攻击动作,不播后续特效
冲撞----->冲撞状态 被冲撞----->被冲撞状态
受伤---> hurt
die----->死亡状态
采集---->采集状态
实时战斗系统问题
人物动作处理策略:
由于某些原因 当前处理的动作还没有结束,又收到了一个要处理的动作协议,处理方式有以下几种: 1 直接将人物状态设置成当前的目标状态,然后开始新的动作。2按照当前的流程处理当前动作,并且把要处理的动作入队列,然后一个一个的执行。。
可能产生的问题:
a:正在移动,网络发来攻击行为 位置不一致
b:正在攻击,网络送来移动行为 位置不一致
c:正在攻击,网络发来新的攻击行为,表现不一致
处理原则就是:优先保证位置一致,然后在保证表现上一致。。。
技能释放前提:cd 距离 魔法量 目标
技能释放的要素:
从当前位置释放,作用于目标要判断距离
在当前位置朝当前方向释放技能
在当前方向朝鼠标方向释放技能
施加于自身的技能 不用判断距离
有些特殊的 群体治疗术 群体隐身术 单体治疗术 单体隐身术