有关位置同步的方案实际上已经比较成熟,网上也有比较多的资料可供参考。在《带宽限制下的视觉实体属性传播》一文中,作者也简单提到了位置同步方案的构造过程,但涉及到细节的地方没有深入,这里专门针对这一主题做些回顾。

最直接的同步方案就是客户端在每次发生位置改变时都向服务器报告 ,服务器再转发给周围的其他玩家,其他客户端将对应的游戏实体移动到新的位置上。

但是这样存在一个问题,每个玩家的位置都是自己先开始移动,一段时间之后才在其他玩家的客户端上表现出来。如果只是希望每个客户端上看到的游戏对象都同时开始移动,那可以让玩家的每一步操作都由服务器确认之后再执行,这样误差将缩减到不同客户端之间的网络延时差。但是显然的,这样的做法不可能真正被采用,因为这将使得玩家的游戏体验非常的糟糕。有谁能忍受连每走一步路都要卡一下的游戏呢?

既然一定存在先后时间差,那需要一种方法来让不同客户端上看到的玩家位置不至于有太大的误差,尤其是不能有影响到游戏公平性的误差存在。根据误差出现的直接原因:时间差,我们应该能够想到一个解决方案,那就是让其他客户端设法弥补掉这段时间差内少走的距离。这样的话也就要求我们的消息包中多带一个开始移动的时间数据,用于其他客户端在收到这个消息包时计算对应的玩家实体已经移动过的时间和距离。

我们以一个实际的例子来说明如何减少这种误差的影响。假设玩家A以速度V从P1点去到P2点,A的网络延时为T1,在A旁边有个玩家B,他的网络延时为T2。B收到服务器转发过来的移动包时,A在其自己的客户端上已经移动了T1+T2的时间,在这段时间内他自己已经走过了V*(T1+T2)的距离。如果这时在B的客户端上开始将实体A从P1移动到P2,那显然两个客户端上看到的A的位置始终存在V*(T1+T2)的误差。

为了使A在B客户端上显示的位置与其实际位置的误差尽可能的缩小,一个简单的做法是直接将A的位置向前拖V*(T1+T2)然后开始移动,这样两者之间的误差便消除了。但这样会使得客户端的显示太鲁莽,要让其看起来平滑一些,我们可以考虑使用一些算法,比如计算出A从当前位置走到P2点还需要的时间,然后加快其速度使其在规定的时间内到达P2点,这样A和B看到的最终时间是相同的,但中间过程还是存在较多误差。另一种较好的做法是先让A以一个可接受的较快速度移动到其当前应该所在的位置稍前一点的地方,然后以正常速度移动到P2点,这样后面的移动情况与其实际移动情况基本吻合了。

看起来这个方案很完美,但是这里却忽略了一个问题:我们假设的是每次移动时都知道玩家要去的确切位置。这在靠鼠标点击来移动的2D游戏中是正好合适的,但是在WOW一类的靠键盘来移动的3D游戏中却没有办法采用。WOW中的移动消息都只能向服务器报告当前的坐标及朝向信息。

这类移动的位置同步其实也可以采用类似方案,服务器将移动玩家的当前位置信息广播给周围的其他玩家,当然其中也包含了时间戳。当其他玩家收到这个移动包后,表示的是在过去的某个时间里该玩家移动到了这个位置。如果只是简单地将其对应的实体移动到这个位置,那同样的,也存在位置误差。

与上一种情况类似,如果我们知道该玩家的移动速度,再通过数据包中的时间戳,假设该玩家还在以相同的速度朝相同的方向移动,那我们也可以预测出该玩家从开始移动到现在这段时间内他走了多远了距离。我们也可以将其位置做适当的修正,并使其继续移动下去。

我们需要先停下来考虑一下这些算法的部分细节。其中出现了一些数据是否应该包含在我们的每个消息包中,也就是我们需要考虑的另外一个问题:移动同步的消息中应该包含哪些数据,以及这些数据到底应该向哪些玩家广播。

对于2D游戏的情况来说,我们的算法需要的数据有:玩家的速度V,玩家开始移动的时间T0,收到数据包的时间T1,玩家当前位置P1和玩家要去的位置P2。T1和P1从当前客户端上都可以取到,而速度V一般来说不会经常改变,至少不是每次移动时都不一样,所以我们可以为速度的改变设计单独的消息码,这样V值也是可以在客户端上取到的。最后,每个移动消息中包含的数据只需要有移动到的位置P2和开始移动的时间T0。

其他客户端在使用特定算法将玩家移动到P2后会将其停在此处,直到收到下一个移动包时再开始移动。而对于在移动过程中又收到了新的移动包的处理过程基本类似,不做过多描述。

对于3D游戏的情况,算法是基本相同的,但是没有目标点,替换为移动方向,比如是向正前方移动,还是向左或向右移动等。在这种情况下,只要没有收到玩家停止移动的消息,其他客户端上都会以最后一次收到的移动包的状态来继续模拟移动。

所以,在网络偶尔卡一下的时候也会出现一些奇怪的现象。比如WOW中,看到队友直冲冲地走下了悬崖,你刚喊了句“怎么掉下去了?”只见队友又从身后走出来,还冒出一句:“没啊,我就在你旁边!”

关于数据要向哪些人广播的问题,其实很简单,哪些人会看到这个玩家就需要向哪些人广播。不管是直接在主屏幕上看到还是在大地图上看到的代表其位置的一个点。但是,针对不同的人使用的广播策略还是存在差异。

在《带宽限制下的视觉实体属性传播》一文中提出了一个方案很值得参考。该方案提出的基础是因为3D空间透视的原因,离你很远的一个玩家移动了10米,最终在你的显示器上看到的位移可能只有一个象素;而离你不到一米的一个玩家虽然只移动了一米,但最终显示出来的位移可能会有几十个象素。所以,远处玩家的移动并不需要非常严格的关注,但近处玩家的移动同步需要非常高的优先级。

这个方案的实现还依赖于另一项技术要求,玩家的属性更新以一定的频率来进行,更新时比较一下当前属性值与上次更新时的属性值,如果存在差异则通知客户端更新,另外如果中间跳过了某次更新也不会对客户端表现及游戏公平性造成什么影响。比如这里要处理的玩家坐标,第一次移动到A点,第二次从A点又移动到B点,如果移动到A点的更新包没有发送,直接发送了移动到B点的更新包,这将不会对游戏逻辑产生大的影响。

这套方案基本上是为3D游戏的实体属性广播优化而设计的,在2D游戏中很难使用。一是斜45度视角的2D游戏中屏幕顶端、中间和底部任何一个位置上的玩家移动,其距离和象素比是完全相同的,因为画面不存在透视,所以也就没有远处对象更新频率低这一可能。另外2D游戏中的移动与3D游戏也存在差异,具体情况前面有详细描述,2D游戏中基本上每一次移动都需要广播,不能跳过哪一个,否则玩家看到的现象就是在乱跑,这也必将影响到技能的使用等游戏逻辑。

有关位置同步所涉及到的一些技术细节及优化方案上面描述了一部分,但是在实际的应用中是否会使用还是要看具体游戏的需求。比如大话类型的游戏,其本身对位置的精确同步就没有要求,两个客户端上出现一前一后的移动也不会影响任何的游戏逻辑,所以前面提到的同步方案可能都用不上。

而对于一些同步要求很高的游戏,如WOW中盗贼这类职业的需求,上面的方案可能还不够细致,还需要设计更加有效的同步方案。

另外,在位置同步过程中还有一个不容忽视的问题是外挂。我们不能像WOW那样完全依赖客户端,如果没有暴雪那样强硬的封号措施,游戏也就成为了外挂们的温床。所以,如何在服务器端模拟每个客户端的移动,如何检测出客户端是否存在作弊行为,也是需要重点关注的一个问题。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lfhfut/archive/2008/03/20/2198600.aspx

更多资料请查阅:http://www.onlinegamediy.com/thread-19-1-1.html

网络游戏的客户端同步问题相关推荐

  1. 网络游戏的客户端同步问题 .

    有关位置同步的方案实际上已经比较成熟,网上也有比较多的资料可供参考.在<带宽限制下的视觉实体属性传播>一文中,作者也简单提到了位置同步方案的构造过程,但涉及到细节的地方没有深入,这里专门针 ...

  2. 网络游戏开发之同步模式

    网络游戏开发之同步模式 网络游戏如何实现所有客户端玩家信息同步?(如吃鸡中所有玩家的位置同步) 同步模式一般分两种:状态同步和帧同步. 状态同步:状态发生变化后,客户端上传操作到服务器,服务器收到后处 ...

  3. 网络游戏实时动作同步方案手记(1)

    [原创]网络游戏实时动作同步方案手记(1) by AKara 2010-09-07 @ http://blog.csdn.net/akara @ akarachen(at)gmail.com @wei ...

  4. 企业内部在centos7.2系统中必杀技NTP时间服务器及内网服务器时间同步(windows和linux客户端同步)...

    网络时间协议NTP(Network Time Protocol)是用于互联网中时间同步的标准互联网协议.NTP的用途是把计算机的时间同步到某些时间标准.目前采用的时间标准是世界协调时UTC(Unive ...

  5. Silverlight - Validation 客户端同步数据验证

    前文介绍过Silverlight Validation中两个数据验证机制,ValidatesOnExceptions异常捕获验证机制和DataAnnotation验证机制,这两种验证机制,是在Silv ...

  6. 客户端如何修改服务器时间设置在哪里看,客户端同步服务器时间设置在哪里

    客户端同步服务器时间设置在哪里 内容精选 换一换 在创建数据库连接之后,才能使用它来执行SQL语句操作数据.JDBC提供了三个方法,用于创建数据库连接.DriverManager.getConnect ...

  7. netty客户端同步请求实现

    netty客户端同步请求实现 在项目开发中经常会遇到某个请求需要立刻返回结果的请,而我们使用的框架netty是异步的,如何做到同步请求是经常会困惑到刚刚接触netty的同行. 本文使用netty4为标 ...

  8. rsync客户端同步报错

    rsync客户端同步报错 报错原因:密码输入正确但是也不能同步 解决办法:是因为服务器上的帐户密码文件权限不是600,需要把权限设置成600就可以同步过去了

  9. Java实现客户端同步服务器端的数据

    用户在服务器web前端增加.修改.删除了数据后会导致客户端的数据与服务器端的数据不一致.为了能够使客户端和服务器端的数据一致,客户端需要同步服务器端的这些操作.主要的步骤为:"服务器端修改数 ...

最新文章

  1. 信息学奥赛一本通 1143:最长最短单词 | OpenJudge NOI 1.7 25
  2. python 对象转dict_python model对象转为dict数据
  3. 跨考大连理工大学计算机考研,如何备战大连理工大学的计算机考研_跨考网
  4. bzoj 2400: Spoj 839 Optimal Marks(最小割)
  5. Leetcode143. 重排链表 (golang描述)
  6. was日志报检测到cpu饥饿
  7. Android实现查看预览PDF文件功能
  8. python爬取豆瓣T250电影及保存excel(易上手)
  9. 服务器集群速度文件传输,为什么要实现服务器集群
  10. windos下 elasticksearch7.13安装踩坑记
  11. 基于Quick-cocos2d-x 2.2.3 的动态更新实现
  12. ssh免密码登录快速配置方法
  13. 这些开源项目,值得收藏深入研究
  14. 图论学习NO2.图论相关内容了解
  15. Excel导入30万条数据和导出50万条数据方案
  16. Unity实用小工具或脚本——可折叠伸缩的多级列表二(带搜索功能)
  17. zip压缩包带有密码如何解压
  18. JAVA美食预定推荐系统
  19. Sublime Text 2 (for OS X )配置成可以运行基于python3解释器的 .py文件
  20. 快速把数据转换成excel

热门文章

  1. 结构体02:结构体数组
  2. 实验4-2-8 输出整数各位数字 (15 分)
  3. java 找到一行 更换单词_Java实现对一行英文进行单词提取功能示例
  4. 图鸭科技获数千万元A轮融资,金沙江创投领投
  5. ASP.NETMVC Model验证(五)
  6. qt 不允许 dllimport 静态数据成员 的定义_C++类和对象的定义
  7. 育碧2k微软服务器,育碧服务器出现大规模的BUG:影响到多个平台
  8. 吸顶那个叫什么_吸顶式无线ap优缺点(无线吸顶ap是什么)
  9. 打开outlook2010里面的链接显示 “由于本机的限制,该操作已被取消。请与系统管理员联系。”解决方法...
  10. java中如何获取当前文件的物理路径?