零基础学CocosCreator·第九季-网络游戏同步策略与ESC架构

课程里的版本好像是1.9,目前使用版本为3.8.3

开始~

目录

状态同步

一般游戏的同步策略有两种:状态同步帧同步

如下时序图为状态同步

  • c1操作从a走到b再走到c,因为不必关注细节所以c1将a走到c这个信息告诉给服务端
  • 服务端验证这个操作是否合规,将验证结果告诉回c1
  • 同时服务端还将这个信息转发给了c2和c3
  • c2网络比较快,立刻收到了这条数据,根据插值模拟,模拟出c1从a走到c的动作(当然如果请求频率够快将a到b和b到c都告诉了c2,那就模拟的更精细)
  • c3因为网络较慢,过了很久才收到服务端的数据,此时c1已经做下一个动作了,那c3就会采取一个瞬移或加速的方式模拟c1的移动

优点:

  1. 容易断线重连(因为数据都在服务端)
  2. 容易防外挂(因为逻辑都在服务端)
  3. 简单粗暴(客户端只需获取服务端数据并展示)

缺点:

  1. 服务器压力大(需要承担很大的计算量)
  2. 流量大(数据均由服务端传送过来)
  3. 不同玩家屏幕表现不一样

帧同步

帧同步的计算全部在客户端,服务端只负责做每帧收集操作,合并操作并且转发

那么问题来了,怎么保证所有客户端结果相同?
相同输入 + 相同逻辑 = 相同结果
逻辑层和显示层的分离

  • 同一帧,c1想要 移动,c2想要进行攻击,他们将数据都发送给了服务端
  • 服务端只进行合并转发,给两个客户端
  • c1收到了c1想要移动,c2想要攻击的数据,并进行模拟
  • c2同样收到了c1想要移动,c2想要攻击的数据,并进行模拟
  • 下一帧中客户端都没有操作,没有数据传给服务端,服务器同样进行发送操作

注意:

  • 现代网游用这种模式,当c2掉线了,服务端仍然逐帧执行,c1并没有受到影响
  • 而老代网游模式,每一帧客户端都需要给服务端传送数据(没操作也要传),当c2掉线后,服务端发现收不到c2的数据就会锁帧,所有客户端都需要等待,直到再次所有客户端的数据
  • 再老代网游,如果有一个客户端网速很慢,客户端就会拉长帧时间去保证每个客户端的帧更新是同步的,会导致网速快的客户端也很慢
    优点:
  1. 流量低(所有逻辑都在客户端)
  2. 方便做录像功能(直接客户端再次执行运算逻辑即可)
  3. 服务器逻辑简化
    缺点:
  4. 有可能作弊
  5. 需要保证各端运算结果一致性(比如随机数,无限小数等)
  6. 实时性要求比较高(帧同步的特点就是每秒同步很多次)
  7. 断线重连需要重新跑所有逻辑(可优化)

状态同步和帧同步比较

帧同步客户端

客户端职责:

  1. 玩家操作不直接处理,而是发送给服务器
  2. 收到服务器一帧数据,模拟一帧
    (?帧同步但是逻辑在服务端)

代码实现\]在下面👇 ## 帧同步服务端 具体步骤可以看[之前的文章](https://blog.csdn.net/qq_39685400/article/details/118162983?spm=1001.2014.3001.5502) 还是再总结一下: > 快速开始NodeJs项目 `npm init -y` > > 安装TS `npm install typescript --save-dev` > > 安装WS `npm install ws --save-dev` > > 安装提示 `npm install @types/ws --save-dev` > > 生成tsconfig.json `tsc --init` > > 安装即时编译 `npm install ts-node --save-dev` > > 添加nodemon `npm install nodemon --save-dev` 服务端职责: 1. 把玩家加入到一局游戏中,下发初始消息 2. 每一帧收集操作,合包转发 [代码实现(客户端+服务端)](https://download.csdn.net/download/qq_39685400/90367382) ## ECS框架概念 ### ECS的解释 * E - Entity 实体 * C - Component 组件 * S - System 系统 ### ECS的特点 * 网络-数据-逻辑-显示层相互独立 * C/S端可以运行同一份逻辑代码,方便验证作弊 服务端没有creator内api,逻辑显示放在一起的话,服务端跑不了 * 可以方便的进行预测和回退 ### Entity * 每个Entity对象都有不同的EntityId * Component挂在的对象,同种类型的Component只能拥有一个 * 提供Component的增删查和备份 ### Component * Component只包含数据,不能拥有逻辑函数 * Component挂载在Entity上 * ComponentId使用不同的位来区分(因为Component操作比较频繁,所以需要使用位运算效率优化) [位运算](https://www.runoob.com/w3cnote/bit-operation.html) ### System * System只拥有逻辑,不能包含数据 * System拥有不同Type,比如逻辑帧System,渲染帧System * 依靠SystemType来确定执行顺序和每帧执行次数 * onUpdate函数由系统自动触发,不能手动调用 ### World * ECS世界的入口,单例 * 驱动System和Update * 提供Entity的增删查功能 * 使用forEach根据ComponentId组合来遍历Entity ## ECS实现 [实现代码](https://download.csdn.net/download/qq_39685400/90145467) ### 逻辑帧\&渲染帧 如下图,为一帧执行的内容和不同机器的运行速度 * 我们期望1s内能执行60帧,每一帧执行一个逻辑帧和一个渲染帧,那就需要每一帧耗时不超过16.6ms * 高性能机器每一帧耗时16ms(8+8),可以满足1s执行60帧 * 低性能机器每一帧耗时24ms(12+12),无法满足1s执行60帧,那就会优先执行逻辑帧,不执行渲染帧,去满足1s执行60次逻辑帧,保证高低性能机的逻辑次数一致,以确保执行结果相同 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/0955aad112d44bdc9039a04f66901724.png) ## ECS框架使用 实现和使用放在一起了 使用ECS实现一个简单的demo(箭头旋转前进) [实现代码](https://download.csdn.net/download/qq_39685400/90145467) ## 帧同步\&ECS [代码实现](https://download.csdn.net/download/qq_39685400/90374038)

相关推荐
寻找优秀的自己2 个月前
Cocos Creator 3.8 2D 游戏开发知识点整理
cocos
adminwxs3 个月前
【Cocos TypeScript 零基础 7.1】
前端·javascript·typescript·cocos
la_vie_est_belle4 个月前
《Cocos Creator游戏实战》非固定摇杆实现原理
游戏·cocos creator·游戏开发·cocos·非固定摇杆
末零5 个月前
Cocos编辑器
cocos
jc_caterpillar5 个月前
Cocos使用精灵组件显示相机内容
cocos
一丝晨光6 个月前
Web技术简史、前后端分离、游戏
前端·javascript·css·游戏·unity·前后端分离·cocos
爱你的魔7 个月前
cocosCreator屏幕适配导致的获取node宽高不准问题分析
cocos2d·cocos
草字8 个月前
cocos 触摸2d屏幕拖动3d节点思路
3d·cocos
Lampard猿奋9 个月前
【游戏客户端】大话slg玩法架构(三)建筑控件
游戏·unity·cocos·cocos2dx·slg·游戏客户端