【muzzik 分享】Cocos 物理帧同步

# 前言

之前没研究帧同步,这是我前端时间没上班时边玩边搞做的 Demo 研究成果,总共时间一周(实际2-3天),发布的目的也很简单,打破技术垄断,才能诞生更高端的技术成果。而且就算我没发这篇帖子,迟早也会有相同想法的人发布

# 帧同步

这里我不会说太多,网上也有很多教程,我并没有看太多,只是说说自己的看法

1. 了解帧同步

同步操作而不是状态

帧同步简单的说就是同步玩家的操作而不是状态,比如向服务器发送我按下了什么按键就是传递操作,而发送位置数据就是传递状态。

保证同步一致性

帧同步为什么叫帧同步?因为客户端的游戏进程是根据服务器下发的帧数据推进的,每下发一帧则更新一次游戏,确保了所有客户端展示一致

  1. 问题:服务器需要发送什么数据给客户端?
    答案:当前帧下标,所有玩家的操作数据

  2. 问题:客户端怎么发送操作数据到服务器?
    答案:统计当前帧产生的操作,在下一帧统一发送给服务器,在这里客户端需要筛除无用数据,例如只能执行一次的两个相同操作数据。

重连

帧同步需要服务器缓存从游戏开始到当前为止玩家的操作数据,然后在玩家重连时将所有数据发给客户端,客户端则根据帧数据同步游戏直到和当前帧一致,才算重连成功,所以这也是为什么帧同步游戏重连时间长的原因

相信到这里你已经简单了解了帧同步的原理。那么我们继续进行了解怎么做物理帧同步。

2. 帧同步的优化

预测和回滚

预测:就是按照你的游戏逻辑预测玩家的操作,例如 lol 网络卡时候的惯性移动就是预测

回滚:在预测之前记录当前数据,接收到服务器帧数据后,如果结果和预测结果一致则不回滚,不一致则用记录数据回滚到之前的状态

# 物理帧同步

1. 已知规则

  • JavaScript 的浮点基础运算在各个平台是一致的(遵守ECMAScript 2015 (ES6))

https://stackoverflow.com/questions/42181795/is-ieee-754-2008-deterministic

  • JavaScript 三角函数是提供了建议实现,实际只需要达到近似值即可满足要求,所以在各个平台可能并不一致

https://262.ecma-international.org/6.0/#sec-function-properties-of-the-math-object

https://forum.cocos.org/t/topic/155837

  • WASM 的浮点运算是确定性的

https://forum.cocos.org/t/topic/155837/4

  • C++ 的浮点数运算需要确保相同的架构和编译器才能确保一致

https://stackoverflow.com/questions/20963419/cross-platform-floating-point-consistency

2. 帧同步

  • 手动物理引擎步进:非手动控制步进会导致物理世界运算(step)次数不一致,导致最终的结果差异
    设置自动步进:cc.PhysicsSystem2D.instance.autoSimulation = false;
    cc.PhysicsSystem2D.instance.enable = false 需要在脚本加载时被执行,防止物理世界自动执行 step

  • 预测:使用渲染预测,物理世界依旧暂停,只控制渲染移动。回滚时只需要控制渲染位置即可

  • 确保物理世界数据的一致性:在 Cocos 的物理引擎实现中,通常只是做一个接口同步物理和渲染,所以物理引擎内还存在刚体的坐标与旋转数据。为了确保多端的物理世界数据一致,需要确保节点的 世界坐标世界旋转 在多端一致,具体可以自行查看物理引擎的 syncSceneToPhysics 实现。
    在这里插入图片描述

  • 重置物理引擎实例:个人推测也是因为设备间物理世界运算次数不一致导致的。解决方式为要么根据服务器指令结束物理循环(运算相同次数),要么重置物理引擎实例
    https://forum.cocos.org/t/topic/136991?u=1226085293

3. Web 帧同步

  • 修改三角函数:在我个人测试中,safari 和 chrome 的表现结果一致,但由于三角函数的不确定性,建议还是修改三角函数为确定性实现。并不一定需要使用查表法(提前存储结果),由于 JS 四则运算的一致性,我们可以使用 JS 自身实现,这里推荐使用 stdlib 库。

  • 检查物理引擎源码:在部分物理引擎中,为了更快的速度,有些会使用 let xxx = Math.cos 这种方式调用数学库实现。所以需要检测物理引擎源码,例如 box2d 就是这样
    在这里插入图片描述

4. 原生/多端 帧同步

  • 使用 js 或者 wasm 类型的物理引擎,C++ 需要保证相同架构和编译器,才能防止语言带来的浮点数差异

  • 使用定点数物理引擎,例如 repper.js
    https://forum.cocos.org/t/topic/133618/44

如果想要确定 Web 和 原生使用的物理引擎是否为同一语言,可以自行查看引擎原生代码是否包含这个物理引擎,例如 Physx 就有 C++ 版本

引擎 Web 代码路径:resources\resources\3d\engine\cocos
引擎原生代码路径:resources\resources\3d\engine\native\cocos

示例项目

只做了简单的同步,没做追帧、预测、回滚
服务端 Nodejs

https://github.com/1226085293/PhysicalFrameSynchronization

测试环境:Safari + Windows Chrome

参考资料

  • 理解确定性:https://shaderfun.com/2020/10/25/understanding-determinism-part-1-intro-and-floating-points/

# 结语

对于有物理同步需求的回合制游戏来说,你甚至不需要帧同步,只需要做到上面说的要求,一样可以做到物理同步,例如 台球

好了,快去做出你心仪的游戏吧,不必为技术困扰,另外加入我技术群的小伙伴可以提前知道我发布的最新技术成果哦。

🐧企鹅2群:348096019
🐧企鹅群:200351945

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/617024.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

重生奇迹mu战士攻略有哪些

1、生命之光:PK前起手式,增加血上限。 2、雷霆裂闪:眩晕住对手,战士PK战士第一技能,雷霆裂闪是否使用好关系到胜负。 3、霹雳回旋斩:雷霆裂闪后可以选择用霹雳回旋斩跑出一定范围(因为对手下一招没出意外…

Mybatis技术内幕-基础支撑层

整体架构 MyBatis 的整体架构分为三层, 分别是基础支持层、核心处理层和接口层。 基础支持层 基础支持层包含整个MyBatis 的基础模块,这些模块为核心处理层的功能提供了良好的支撑。 解析器模块 XPathParser MyBatis提供的XPathParser 类封装了XPat…

SpringCloud使用Nacos作为配置中心实现动态数据源切换

一、Nacos-Server 了解Nacos可以直接阅读官方文档 使用Nacos,我们需要有Nacos-Server,此处就不使用官方提供的release版本了,而是自己编译,因为本来就是Java开发的,所以对于Javaer来说也没啥难度! git c…

记nrm管理仓库以及发布npm包

前言 记一次在公司创建私有库以及发布npm包,留下个脚印 一、nrm是什么? nrm是 npm 镜像源管理工具,用于快速地在不同的 npm 源之间切换。 二、使用步骤 1.全局安装nrm 代码如下(示例): npm install -…

Git系列:git diff使用技巧

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

【智能算法】鹭鹰优化算法(SBOA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.代码获取 1.背景 2024年,Y Fu受到自然界中鹭鹰生存行为启发,提出了鹭鹰优化算法(Secretary Bird Optimization Algorithm, SBOA)。 2.算法原理 2.1算法思想…

Elasticsearch查看集群信息,设置ES密码,Kibana部署

Elasticsearch查看集群信息,设置ES密码,Kibana部署 查看集群信息查看节点信息查看集群健康状态查看分片信息查看其他集群信息 Kibana部署安装设置ES密码 查看集群信息 查看节点信息 curl http://127.0.0.1:9200/_cat/nodes?v 参数说明: ip…

OpenGL导入的纹理图片错位

在OpenGL中导入图片的纹理照片的函数为 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, p_w, p_h, 0, GL_BGR, GL_UNSIGNED_BYTE, pic_data);其中p_w, p_h为图片的宽和高,pic_data为指向图片存储空间的的地址(unsigned char *类型) 在OpenGL中图片默认是4字节对齐的&…

Web开发小知识点(二)

1.关于取余 我在Dart语言里(flutter项目) int checkNum (10 - 29) % 10; 那么checkNum等于1 但是在Vue项目里 const checkNum (10 - 29) % 10;却等于-9 语言的特性不同,导致结果也不同,如果要想和Dart保持一致,…

vue3.0(六) toRef,toValue,toRefs和toRow,markRaw

文章目录 toReftoValuetoRefstoRowmarkRawtoRef和toRefs的区别toRaw 和markRaw的用处 toRef toRef 函数可以将一个响应式对象的属性转换为一个独立的 ref 对象。返回的是一个指向源对象属性的 ref 引用,任何对该引用的修改都会同步到源对象属性上。使用 toRef 时需…

[蓝桥杯 2021 国 ABC] 123(java)——前缀和,思维

目录 题目 解析 代码 这么久了,我终于能不看别人代码完整写出来了,呜呜呜。虽然过程也是很曲折。 题目 解析 这个题,找其中数列的规律,1,1,2,1,2,3,1,2,3,4,...,因此我们把拆分成行列,如下…

Java并发处理

Java并发处理 问题描述:项目中业务编号出现重复编号 生成编号规则:获取数据库表最大值,然后再做1处理,即为新编号(因为起始值是不固定的,还存在‘字符数据’格式,做了字典项可配置,所以不能直…

Ai 一键美术绘画文章,蓝海项目,流量巨大,盈利成效显著

今天我要向大家介绍一个全新的蓝海项目,那就是AI一键美术绘画文章。这个项目打破了传统的思维模式,更加吸引人的眼球,已经在各大网站上引发了大量的关注,轻松在抖音上热门也变得简单易行且稳定。 下载 地 址 : laoa…

PopClip for Mac 激活版:让文本处理更高效

还在为繁琐的文本处理而烦恼吗?PopClip for Mac来帮您解决!这款神器般的文本处理工具,能让您轻松应对各种文本处理任务。无论是写作、编程还是日常办公,PopClip for Mac都能助您一臂之力,让您的文本处理更高效、更便捷…

【基础绘图】 09.小提琴图

效果图: 主要步骤: 1. 数据准备:生成随机数组 2. 数据处理:计算四分位数、中位数、均值、最大最小值 3. 图像绘制:绘制小提琴图 详细代码:着急的直接拖到最后有完整代码 步骤一:导入库包及…

动态规划----股票买卖问题(详解)

目录 一.买卖股票的最佳时机: 二.买卖股票的最佳时机含冷冻期: 三.买卖股票的最佳时期含⼿续费: 四.买卖股票的最佳时机III: 五.买卖股票的最佳时机IV: 买卖股票的最佳时机问题介绍:动态规划买卖股票的最佳时机是一个经典的…

排序2——冒泡排序,快速排序(3种递归方式+3种非递归方式)

目录 1.交换排序 2.冒泡排序 2.1基本思路 1.1.2复杂度分析 3.快速排序 3.1基本思想 3.2Hoare版本(最初的) 3.2.1缺点 3.2.2优化 第一种——随机选key 第二种——三数取中 第三种——小区间优化 3.3挖坑版本(更好理解&#xff09…

【谷粒商城】01-环境准备

1.下载和安装VirtualBox 地址:https://www.virtualbox.org/wiki/Downloads 傻瓜式安装VirtualBox 2.下载和安装Vagrant官方镜像 地址:https://app.vagrantup.com/boxes/search 傻瓜式安装 验证是否安装成功 打开CMD,输入vagrant命令,是否…

pyqt5将ui文件转为python文件

在pyqt5中使用 pyuic将ui文件转为py文件: 例如:将home.ui文件转为vio_detect.py文件,所需命令如下: pyuic5 -x home.ui -o vio_detect.py

【Linux】基于 Jenkins+shell 实现更新服务所需文件 -->两种方式:ssh/Ansible

👨‍🎓博主简介 🏅云计算领域优质创作者   🏅华为云开发者社区专家博主   🏅阿里云开发者社区专家博主 💊交流社区:运维交流社区 欢迎大家的加入! 🐋 希望大家多多支…