`
wsliujian
  • 浏览: 95128 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

影子跟随算法:FPS游戏中游戏同步性的实现

 
阅读更多

影子跟随算法:FPS游戏中游戏同步性的实现

发布者: 小篱 | 发布时间: 2015-8-17 14:36| 评论数: 2

 

游戏程序 平台类型: 程序设计: 编程语言: 引擎/SDK:
Web/页游 
算法逻辑/智能AI 服务器 网络通讯 
 
 

本帖最后由 小篱 于 2015-8-17 15:00 编辑

影子跟随算法:FPS游戏中游戏同步性的实现 ...


  GameRes游资网授权发布 文 / 韦易笑

  何为延迟补偿?如何进行坐标差值?B客户端屏幕上A已经跑到东边了,但是收到服务器说“A正在西边往北跑”,B到底该何去何从?我若干年前的一个实现版本,将简明扼要的解决这个问题:

  影子跟随算法由普通DR(dead reckoning)算法发展而来,我将其称为“影子跟随”意再表示算法同步策略的主要思想:

  屏幕上现实的实体(entity)只是不停的追逐它的“影子”(shadow)。

  服务器向各客户端发送各个影子的状态改变(坐标,方向,速度,时间)。

  各个客户端收到以后按照当前重新插值修正影子状态。

  影子状态是跳变的,但实体追赶影子是连续的,故整个过程是平滑的。

影子跟随算法:FPS游戏中游戏同步性的实现 ...


  前面的1号终端控制红色飞船P1向左飞,并把自己的状态时时告诉服务器。

  后面的2号终端上接收到飞船P1的影子S1的状态(向左移动),并让P1的实体追赶S1。

  网络性能指标一:带宽,限制了实时游戏的人数容量。

  网络性能指标二:延时,决定了实时游戏的最低反应时间。

  使用该算法可以容易的开发出一款马里奥赛车,或者Counter Strike,详细说明见后:

  算法比较:

  帧间同步:不同客户端每帧显示相同的内容,键盘/时钟数据传到服务器,服务器确认后所有终端做出响应,多用于局域网游戏,比如红警(需要等待客户 端),街霸II的网络版(360),可参考 LockStep,TimeWrap算法,网速要求高,复杂度低,见我的旧文帧锁定算法。

  插值同步:不同客户端显示不同步,但是状态同步,常见的Dead Reckoning(或叫导航插值),效果好,但复杂度高。常见于竞速类游戏和 FPS游戏。

  算法定义:

  时间:单位为帧(FPS=10),开始由服务器告诉向所有客户端,每5分钟同步。

  玩家:每个玩家控制自己的实体,并在每贞将状态改变告知服务器。

  状态:状态数据 = 实体ID + 坐标 + 方向 + 速度 + 时间(贞)。

  插值:收到新状态包后将根据其运动方向与时间,根据现有时间计算新状态。

  跟随:实体不停的追踪自己的影子,追上后与影子保持状态同步。

  相位滞后:可选参数,实体与影子保持一定距离同步,相当于保持一定车距,这样在控制者突然停止的时候,不容易因为网络延迟跑过了又被拉回来。

  惯性移动:可选参数,开始移动或者停止或者改变方向都有加速度,这样就不需相位滞后了。

  每次服务器向各个客户端同步时间的时候,由于延迟,所有客户端的时间都是慢于服务器的,这没有关系,只要大家在一定误差范围内以相同的速度增加,就完全没有问题。

影子跟随算法:FPS游戏中游戏同步性的实现 ...

 

图2 IDC网络响应


  在公网平均130ms的Latency下,是不存在“完全的”的同步情况。如何通过消除/隐藏延时,将用户带入快速的交互式实时游戏中,体验完美的互动娱乐呢?

  让所有的用户屏幕上面表现出完全不同的表象是完全没有问题的;

  把这些完全不同表象完全柔和在一个统一的逻辑中也是完全没有问题的。

  需要根据具体情况,分清楚哪些我们可以努力,哪些我们不值得努力,弄明白实时游戏中同步问题关键之所在,巧妙的化解与规避游戏,最终在适合普遍用户网络环境中(200ms),实现实时快速互动游戏。

  案例解析:Counter Strike

  实现CS的话,首先我们需要给人物移动加上惯性,比如静止状态突然开始移动,那么需要0.5-1秒的加速过程,而移动中突然停止也需要0.5-1秒的减速过程,这样就实现了无差别同步,不需要相位滞后来避免拉扯影响用户感。

  同时开枪射击采用客户端判断,也就是说如果我看见你在墙前面,开枪射中,那么我向服务器发送“我击中你了”,这时有可能真实的你在墙后,那么表现出来的就是我看见我打中你了(减不减血由服务段判断),而你没有看见我,觉得我穿墙打中你了。

影子跟随算法:FPS游戏中游戏同步性的实现 ...

 

图3 CS的同步逻辑


  关键状态进行缓存,不然如果别人向前连续跳五次,每次取得状态都取到最高点的话,别人客户端上的影子和跟随的实体会奇怪的持续的飞在天上,所以需要将起跳和落地这两个关键状态缓存,实体追赶时只有追上的第一个状态(一号影子)才能追逐第二个状态(二号影子)。

  由此可以在完全时间同步的情况下平滑的跑动、跳跃,开枪射击采用客户端判断后手感得到提高,唯一需要担心的就是外挂,外挂多是实时游戏的代价,只能通过Cheating Death等工具防止了。

  案例解析:马里奥赛车

  用该算法实现马里奥赛车是很简单的,影子和实体都使用惯性,由于赛车惯性很大,不容易有突变的状态更新,所以效果会比FPS游戏更好。

  玩家碰到道具后,马上在屏幕上隐藏该道具的显示并通知服务器,由服务器决断道具属谁,由于刚碰到道具就隐藏所以不会有碰到道具却在一段时间内无法取得延迟现象。

  游戏道具系统实现也很容易,比如那个将当前第一名炸毁的道具,它的描述是:原角色+对象角色+约定发生时间。既然知道对象是谁,什么时间发生,那就更本不需要怎么同步了,所有客户端和服务器在该时间让地雷爆炸就得了,这种手法类似即时战略游戏。

  游戏还有一类道具是可以发射的乌龟壳,这个东西属于有弹道的发射物,类似Quake里面的某些武器,需要作一些同步处理,基本特性是服务器判断起决定 作用,客户端同步判断,如果客户端与服务器都判断集中,那就集中;如果客户端判断集中而服务器判断没有集中,那会看到该角色似乎被打了一下,但很快又恢复 了速度向前冲。

  由于赛车本身就具备惯性比较大的特点,因此同步效果是比较好的,可以在更大的延迟情况下表现得和FPS差不多(比如300ms效果相当于FPS的200ms)。
非可靠包:

  该“影子跟随算法”支持非可靠传输协议,如果使用非可靠传输,那么我们按照特定频率(如每秒10次)定时发送状态更新,因为协议中每个更新包出了位置 外还有速度、方向和时间,甚至还能加速加速度,因此我们丢一个包没有关系,可以根据后来的包重新计算插值。只有关键状态更新时才需要可靠传输,这就避免了 TCP中丢包时RTO指数增长造成的延迟了。

  负面情况:

  该算法缺点就是无法向“帧间同步”算法那样,每次发送按键给服务器,服务器处理后再反馈结果,在局域网中(平均延迟<5ms),这样的效果相当 于单机游戏一样即时,游戏性也能很复杂。然而在Internet中(平均延迟130ms,设计基准200ms,每秒最多发送10个数据包)该算法却不能像 单机游戏那样有复杂的场景互动,有类似格斗游戏的即时的动作判定。

  许多策划在设计实时动作游戏时很多设计我们都难以实现,这样因为策划不容易明白哪些我们能做,哪些我们不能做。即便程序员精通同步理论,策划也经常碰壁。
当多数设计被程序员回复“无法实现”后,策划只有采取一种消极设计(砍掉很多有意思的互动元素),于是网络游戏的表现力到今天还是差单机游戏一大截。

  这些问题也并不能因为“影子跟随算法”的提出而得到改进,大于100ms的判定时间,都很难做到即时。

  最后,该算法编码复杂度比其他同步策略高,因为服务器需要计算一份影子数据,各个客户端需要计算一份影子数据,还需要计算实体追赶,而这三种计算都需要在同样的时钟下保持一致,这就增加了编码与调试的复杂度。

  总结话题:

  Internet特点是“高带宽,高延迟”,可以说从本质上Internet就不是为了游戏而设计的。故此Internet绝对意义的同步是不存在 的。“影子跟随算法”的核心思想有几个:时钟同步,客户端先行,平滑追赶。通过这三个特性,我们能够在近似时间同步的情况下,模拟各种物体的移动过程,而 使用该算法的前提是设计者需要根据各个游戏的特性研究不同的优化技巧,策略因游戏而变。

  比如发送状态更新包时,不需要每次都发送,而可以只发送改变的状态。什么时候我们觉得改变了?就是当客户端实体与自己的影子之间的误差大于某特定数值 时我们才发送更新包,这样虽然玩家在原地做左右摇摆的小幅度移动,只要没有超出范围,都不需要发送新的状态更新,其他玩家机器上看起来,它是站着不动的。

  比如当发现某客户端5秒钟没有相应了,那么就将该人物的影子冻结住,永远不要为了等待某个数据而不让游戏进行下去。

  本算法需要客户端与服务器维护相同的时钟,当每5分钟同步的时候,直接根据服务器的时钟替换当前时钟就行了,不需要重新计算所有影子的位置,因为后续的状态数据将会马上刷新这些状态。更不需要将测量到的PING值考虑进去,该算法与PING具体值无关。

  当发现策划案子不可行时,寻找近似替代方案,比如减少“一次性的”“决定性的”事件发生,比如延长导弹在空中飞行的时间,比如将敌人加入HP分多次打死,而不是以及毙命,等等,都是大家可以发挥想象的地方。

分享到:
评论

相关推荐

    算法:C语言实现(第1~4部分)答案

    在本资源中,我们主要关注的是使用C语言实现算法的解答,这涵盖了算法的第1到第4个部分。C语言是一种广泛用于系统编程、应用编程、嵌入式系统以及编写算法实现的强大编程语言。其简洁性和高效性使得它成为学习和理解...

    数据辅助型三种定时同步算法:S&C定时同步算法及仿真、Minn算法及仿真、Park算法及其仿真..zip

    这里我们探讨的是三种数据辅助型定时同步算法:S&C(Shapiro & Cross)定时同步算法、Minn定时同步算法以及Park定时同步算法。这些算法主要用于确保网络中的不同设备或节点在时间上保持一致,从而保证数据的正确传输...

    unity2017算法分析与实现.rar

    7. **网络同步算法**:在多人在线游戏中,网络同步算法确保了玩家间操作的一致性。 通过书中提供的游戏素材,读者可以亲自操作并观察这些算法在实际项目中的应用效果。这不仅加深了理论理解,也锻炼了实践能力。...

    三种成像算法:RD、RMA、CS

    在SAR成像处理中,有三种重要的算法:Range-Doppler (RD)、Random Migration Algorithm (RMA) 和 Compressive Sensing (CS)。下面将详细介绍这三种算法及其应用。 1. Range-Doppler (RD) 算法: RD算法是SAR成像的...

    (2018-2019)FPS游戏 完整版.zip

    FPS游戏,全称为“第一人称射击游戏”,是电子游戏中的一种流行类型,以其紧张刺激的战斗体验和高度的竞技性而备受玩家喜爱。本压缩包文件"(2018-2019)FPS游戏 完整版.zip"包含了2018年至2019年间某款FPS游戏的...

    kay&fitz&mr同步算法_Fitz_kay_同步算法_

    提供的压缩包文件“kay&fitz&mr同步算法”可能包含实现这些算法的MATLAB源代码,通过阅读和理解代码,你可以深入学习这些同步算法的细节,以及如何在实际系统中应用它们。在实际工程中,这些算法的优化和调整是至关...

    java数百种算法实现

    Java是一种广泛使用的编程语言,以其跨平台性和丰富的库支持而著名。在计算机科学中,算法是解决问题或执行任务的明确步骤。"java数百种算法实现"这个资源集合显然是为Java开发者提供了一个广泛的算法实践库,涵盖了...

    多余度机载计算机同步算法研究-郝艳也.pdf

    三、基于同步中断的被动同步算法:提出了一种基于同步中断的被动同步算法,展示了该算法的实现过程和优越性。 四、实验结果:展示了实验结果,证明了基于同步中断的被动同步算法的可行性和优越性。 五、结论:总结...

    基于深度学习的FPS游戏角色检测源码+项目说明+游戏角色数据集.zip

    该项目采用YOLOv5这一流行的实时目标检测算法,旨在帮助用户理解和实现游戏中的角色自动检测与追踪功能。通过使用该资源,用户可以学习到如何在真实FPS游戏环境中应用深度学习技术进行角色识别,并提升游戏体验或...

    OFDM同步算法之SC算法

    正文中: ...总之,SC算法是OFDM系统中实现时频同步的一种重要方法,对于理解和优化无线通信系统的性能具有重要意义。通过深入学习和实践,我们可以更好地掌握这种算法,并应用于实际的通信系统设计中。

    三种帧同步算法的MATLAB代码_帧同步matlab_帧同步算法_帧同步_

    本文将深入探讨三种常见的帧同步算法,并提供MATLAB代码实现,适合本科毕设项目参考。 1. **滑动窗口同步(Sliding Window Synchronization)** 滑动窗口同步是一种基本的同步方法,它依赖于在接收数据中寻找特定...

    电梯调度算法(算法合集)

    5. 滚动优化算法:这种算法结合了动态规划和预测,以周期性地更新电梯的运行计划。它在每个决策周期内考虑未来一段时间内的需求,以实现高效调度。 6. 模糊控制:模糊逻辑允许处理不确定性和模糊的信息,适用于处理...

    游戏开发中的经典算法

    游戏开发中的经典算法是编程实践中不可或缺的部分,它们是解决问题的核心工具,通过精心设计的步骤来指导计算机执行任务。算法的设计和实现是程序设计的核心,它将抽象思维转化为计算机可理解的语言。在这里,我们将...

    卡片游戏-小猫钓鱼1

    3. 牌的发牌算法:游戏中牌的发牌算法是通过一个循环来实现的,循环中使用了array_shift()函数来出牌,并将牌加入到队列中。发牌算法的目的是为了实现游戏的公平性和随机性。 知识点:随机数生成、牌的发牌算法 4....

    Python基于YOLOv5目标检测算法开发的FPS射击类游戏辅助瞄准系统源码+项目说明.zip

    Python基于YOLOv5目标检测算法开发的FPS射击类游戏辅助瞄准系统源码+项目说明.zip本资源中的源码都是经过本地编译过可运行的,资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、使用需求,如果有...

    网络游戏-无线传感器网络时间同步算法研究.zip

    研究中,我们重点关注了几种常见的时间同步算法: 1. **精密时间协议(Precision Time Protocol, PTP)**:PTP是一种广泛应用于局域网的时间同步协议,其设计目标是实现亚微秒级的精度。在网络游戏环境中,PTP可...

    基于yolov8实现的AI自瞄项目.zip

    基于yolov8的FPS游戏自瞄软件 实现基本的自瞄功能等。 基于yolov8的FPS游戏自瞄软件 实现基本的自瞄功能等。 基于yolov8的FPS游戏自瞄软件 实现基本的自瞄功能等。 基于yolov8的FPS游戏自瞄软件 实现基本的自瞄...

    基于matlab无线传感器网络时间同步算法

    时间同步对于WSN的协调操作至关重要,确保数据收集的一致性,减少时序错误,支持多跳通信中的路由算法,以及实现分布式计算和事件检测。 2. **常见的时间同步算法**: - **基于参考广播的时间同步(Reference ...

    raft算法简单实现-java

    RAFT算法是一种分布式一致性协议,主要用于在集群中复制日志,确保数据的一致性。与PAXOS算法相比,RAFT算法以其简洁性和可理解性而受到欢迎。在JAVA中实现RAFT算法,可以为分布式系统提供可靠的领导者选举和状态机...

    各类matlab OFDM同步算法

    1. Moose同步算法:Moose算法是一种基于导频的时钟恢复方法,适用于OFDM系统中的载波和符号同步。它通过检测导频符号的相位变化来估计系统时钟偏移,从而实现时间对齐。在MATLAB中,可以通过设计匹配滤波器和计算...

Global site tag (gtag.js) - Google Analytics