前言
接触了大概半年时间的Cocos Creator,做过不少同步类的游戏,其中多数的双人对战类游戏大多游戏我都选择了状态同步,这主要是因为个人开发习惯导致,个人也更加熟悉状态同步,另外H5类小游戏大多是轻量级的游戏,所以不比ACG类手游、端游要求高,使用帧同步的小游戏就特别少。
最初在入行小游戏时,觉得H5小游戏的帧同步技术上的实现是非常麻烦的,因为H5小游戏的协议用的是WebSocket,而WebSocket协议是HTTP的升级版,通常来说,HTTP的传输层协议用的是TCP,为了保证数据的可靠性,降速在所难免,所以帧同步基本不会考虑使用TCP做传输层协议。也正因为TCP,所以当初的考虑是觉得WebSocket协议上实现帧同步,这样的同步效果是非常差的。
这样的想法在我脑子里持续了很久,后来想到,两年前很火的 IO 类H5小游戏,协议也是WebSocket,却也实现了同步,并且还是多人游戏,要知道客户端越多,状态同步压力是越大的,这也意味着这些IO类游戏极可能用的就是帧同步。
Top IO Games in October 2019iogames.space
后来查阅了大量资料,自己操作一番,总算是把一个基本的帧同步实现了,运行起来还算OK,暂时没发现有严重延迟或者卡顿问题。这里抛转引玉分享出来。
客户端继续用的是Cocos Creator,服务器用的是开源的 Colyseus。
服务端 Colyseus 源码地址:
https://github.com/colyseus/colyseusgithub.com
客户端的实现
BUGyyc/LockStepH5github.com
按照帧同步的思路,我们需要将游戏推进的决定权交给服务器,服务器通知客户端去进行下一帧,游戏才会继续。
为此,我们需要暂停游戏
直到收到服务器的指令,进行下一帧
加速表现丢失的帧
加入游戏房间
通过IP及端口号,创建或加入房间
游戏的推进
在接收到服务器消息后,我们需要对消息进行对应的处理。如下,我们将帧数据缓存在 frames,并且按顺序执行,这样保证了有序执行游戏逻辑。
拿到帧数据后,从 frames 中取缓存好的指令,按顺序执行。
runTick 对应执行玩家的操作广播、以及玩家的创建广播
服务端的实现
客户端同学很有必要了解一下服务端的实现
游戏房间
在index.ts 定义了游戏房间,并且给定了名称,客户端连接时,需要指定房间名称,或者房间ID,这里采取的是名称的方式
服务器处理消息
服务器接收到客户端消息后,进行响应。其中 onGetAllFrames 使得重连的玩家,不至于丢失所有游戏进程,有一个表现过程。
演示流程
客户端源代码
BUGyyc/LockStepH5github.com
服务器源代码
BUGyyc/colyseus-examplesgithub.com
启动服务器
在服务器代码路径下执行命令:
如果首次clone代码,可能需要在clone 后,执行 npm install
执行 npm start 启动服务器,监听2567端口
然后服务器就启动成功了,根据客户端指定的房间名称,玩家就可以加入房间进行游戏
其他
还有需要进一步完善的地方:
需要解决随机种子的问题,保持多个客户端随机数一样。
物理引擎的确定性问题,如:浮点数计算偏差
作者:Delevin
推荐本站淘宝优惠价购买喜欢的宝贝:
本文链接:https://www.hqyman.cn/post/7330.html 非本站原创文章欢迎转载,原创文章需保留本站地址!
休息一下~~