关于自动寻路和游戏角色同步问题的具体设计

 

1.      对于这样一种情况:

每一次服务器发送给b的关于它们的网络玩家A的角色的移动事件信息时,对于b而言,它们都不一定必须在接受到消息的当前帧执行客户端同步模拟的代码。

这样设计的原因是因为两种原因:

(1)      当网络延迟严重时,b所接收到的关于A’的移动事件消息可能已经过期(即不再是当前时间A’应该做出的处理,(从时间戳可以看出))这种时候我就应该从b客户端中的A’角色所在移动同步事件队列中,将该事件删除,转而将CPU资源用于处理更新更准确的移动事件。

(2)      当同屏过多的玩家角色同时移动的时刻,我可以优先处理距离B角色更近的网络玩家角色,并且优先处理在它的队列中需求最高的事件。

 

 因此,我们必须对每个网络角色对象的移动事件所在的队列进行动态维护。

具体的维护方法可以如下:(ABC 都是在客户端X上显示网络角色)

                      

首先,为了使每个事件都能按照适合的需求被执行,我们采用权值的方式来线性的对每一个移动事件进行处理。权值的大小,取决于4类不同的因数。

(1)      角色的权值:由角色是否能被我看见,距离我的远近,角色的移动等待队列中有多少个正在等待的事件等因素决定。

(2)      事件的权值:由事件的时间戳决定,如延迟了多久,当时间过期,直接删除事件。

(3)      该角色是否在本帧中已经执行过一次移动事件,只能执行一次移动

 

(3)      对于所有的寻路事件,我都将根据该帧需要处理的个数来将其分别在2-5帧内完成(具体根据写代码的时候)。根据人体的神经反应时间,在0.2秒左右的误差,玩家是无法区分的,因此分帧处理是完全不会对游戏的表现效果产生影响。

 

总结:对于一个需要城战的游戏,AreaInteresting 角色列表过于庞大,同一帧接受到数个角色的移动事件这种极端情况就会突然大幅降低客户端的帧速,为了事这种情况下,客户端不至于卡死,我们才得以采用此方法来维护。尽管算法变复杂,但是能使同屏的角色数量大大增加。

 

2.      对于这样一种情况:

 

当a执行一次寻路事件,并且已经被服务器发送到b上面,a’已经开始模拟该事件时,这个时候,a放弃了当前未完成的寻路事件,并执行新的寻路事件(A或者B),事件经由服务器传送到了b上,此时,b上面的a’所在的位置并不等于新的寻路事件的起点,因此,此时所接收到的寻路消息中的节点信息是无效的,为了使其有效,根据当前点和目标起点之间有无碰撞来决定是否由接收客户端自行计算该网络角色的寻路点(将A变成D和C),使之和目标起点组成一串当前有效的寻路节点。

做这样的设计,则需要维护一个临时进行A*寻路计算的需求队列,原因如下:

(1)      避免同一帧进行多个A*寻路算法,完全可以分成数帧来对该队列进行分开处理。

(2)      分帧处理对于客户端感官而言几乎没有影响。

 

3.      客户端和服务器之间通讯的数据结构

(1) 客户端发送到服务器上的数据结构:Send(CurPos,NextNode1,NextNode2);

CurPos: 当前的本地玩家角色A的位置

NextNode1:下一个节点的位置

NextNode2:下下个节点的位置

(2) 服务器收到Send()后,打上当前的时间戳,再转发给AreaInteresting中 有A的客户端

(3) 其他客户端收到服务器发来的消息:

Receve(CurPos,NextNode1,NextNode2,SendTime);

首先,得到本次移动和上一次移动之间的时间差,即该网络角色本次间隔模拟了多少时间了

T = SendTime – lastSendTime;

得到前一次收到信息和本次收到信息之间,该角色移动了多少距离S. 得到当前应该有的速度:

      Vt = S/   T *a;

a为系数,可调。

      如果本次移动信息因网络延迟被间隔了很久才发送过来,那么S必然会很大,而对于服务器的发包时间差而言,不会因网络而影响。所以延迟的结果必然会导致Vt变大,角色会加快速度来弥补位移。则可实现客户端模拟

 

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页