当前位置: 首页 > 科技观察

干货分享:《欢乐坦克大战》微信小游戏开发总结_0

时间:2023-03-17 16:05:13 科技观察

前言  《欢乐坦克大战》是一款支持3V3即时对战的微信小游戏,是首批上线的微信小游戏之一。由于本游戏是微信小游戏中的正经之作,项目开发周期非常短,因此游戏复杂度、开发难度、性能挑战也相当大;项目组在一个月内完成了单机和网络对战玩法的开发。  同时,由于客户端开发团队的核心成员有多年的Cocos2d-x引擎开发经验,所以项目组决定使用CocosCreatorv1.6.1引擎进行开发。至于微信小游戏平台使用的javascript语言,开发团队基本上是从零开始,边学边做,对自己来说是一个很大的挑战。架构  网络通信本项目使用WebSocket协议进行通信,通信格式为json。为了迎合tdr的xml协议,项目组自己开发了一个tdr->json转换工具。  为了方便规划同学使用excel表格进行数据配置,项目组开发了excel转json文件的工具,方便客户端读取配置文件。  在地图方面,我们没有使用cocos引擎自带的TileMap,而是自己实现了一个类似TileMap的机制。规划人员可以在excel中配置地图信息,利用工具将excel转换成json格式的地图文件,供客户端加载。  由于开发进度紧张,需要同时开发单机和PVP玩法。所以我们封装了一个命令层(CMD层)来驱动战斗逻辑。例如,要用摇杆控制坦克的移动,表现层将CMD命令发送给逻辑层进行处理。在单机模式下,CMD会存放在客户端的本地列表中,然后命令管理器CMDMgr在Update时会读取本地的命令列表来驱动逻辑。层进行处理。在对战模式下,CMD命令会发送到服务器,服务器会广播给所有玩家。播放器客户端的命令管理器CMDMgr将在Update时驱动逻辑层进行处理。引入命令层(CMD层)后,战斗逻辑层抽象独立。开发无需关心当前的玩法模式,方便复用,降低开发成本。  我们的PVP实时战斗采用c/s模式的同步架构。客户端进行碰撞检测,并将碰撞检测结果通知服务器。服务器进行校验和伤害计算,然后广播给其他玩家。游戏支持断线重连和客户端崩溃重连机制。服务端拥有战斗中的所有状态数据,重连时将所有数据发送给客户端,客户端还原战斗场景。  玩家位置同步采用基于时间戳的位置点同步算法。该算法最初用于《全民飞机大战》的双打模式和对抗模式。《全民飞机大战》中的实时战斗使用UDP通信。在《欢乐坦克大战的》WebSocketTCP的环境下也取得了不错的效果。算法原理如下:  Challenges  在开发过程中,我们也遇到了很多挑战,但是我们都一一解决了。具体遇到的问题如下:  1.动态代码执行限制  微信小游戏平台增加了动态代码执行限制,如:eval('console.log(1)'),newFunction('console.log(1)'),setTimeout('无法调用console.log(1)')等调用方法。在CocosCreatorv1.6.1的源码中,Function被广泛使用。为了解决这个问题,我们与cocos引擎开发者进行了沟通,参考cocos在1.7版本(当时还未发布)的修改,修改了部分源码,问题得以解决。这个问题。  2.微信小游戏不能超过4M  如题所示,微信小程序对大小有严格要求。为了解决这个问题,我们想了很多办法。  措施一:自定义引擎,剪掉不需要的模块,减小引擎的体积。这可以通过设置引擎模块来完成。  措施二:图片压缩  使用png图片压缩工具pngquant,可以有效减少png图片的文件大小(一般压缩60%-70%左右)。  通过以上两种措施,资源还是会超标,所以只能采用动态资源下载的方案。  措施三:资源动态下载  我们在游戏中加入了资源更新场景。游戏启动时,场景中更新资源时不创建游戏业务模块,而是在游戏场景中创建并初始化业务模块,然后切换场景。具体方案如下:  1.首先下载一个资源更新配置文件,里面包含资源下载列表和资源校验MD5信息。  2.根据资源下载列表,将校验MD5与本地文件进行比对。相同则不下载,不同则下载。  3.下载完成后,进行MD5校验。如果验证不通过,删除本地文件,重新进行下载。这里的MD5校验不仅可以验证资源下载是否正确;对防止资源被恶意修改,资源反作弊也有一定的作用。  4.修改cocos引擎源码,在load-pipeline中,将读取资源替换为读取本地下载文件。  由于游戏运行可能存在BUG,需要下发客户端补丁。资源更新配置文件可能会被多次修改,CDN更新可能会延迟,导致部分玩家下载的配置文件可能是旧版本。而且,一些中小运营商出于成本考虑,会缓存旧文件。在之前的项目中,遇到这种情况,一般都是联系播放器进行定位,查明是运营商的问题后再反馈给运维同学。网络部的同事会催运营商改,效率不高。为了减少这种情况发生的可能性,我们使用双CDN策略。  具体方法是增加同名文件的版本号机制。更新文件时,文件的内部存储版本号会+1,会在两个不同的CDN上进行更新。客户端下载时,下载两个文件,以版本号大的为准。这样在更新配置文件的时候,只需要同步两个不同的CDN中的一个,既减少了CDN的更新延迟,也降低了运营商缓存问题的概率。  3.性能优化  与普通游戏不同,微信小游戏平台本身的js脚本执行效率比较弱。iOS环境小游戏的javascript引擎目前使用JavaScriptCore,默认不开启JIT优化。js执行速度会比手机safari慢。根据简单的测试结果,速度会慢一倍左右。从Profiler来看,js脚本执行时间会占80%左右。因此,减少脚本的计算量也是性能优化的一个重要方面。  优化  为了解决这些问题,项目组做了如下优化。使用图片资源制作拼图。  分为地图背景层、地表、地图物件、坦克、子弹、特效、UI等拼图。尽量保证同一关卡的游戏对象使用相同的图集,相邻的精灵使用相同的材??质。  面具  游戏中会显示玩家的圆形头像,而微信平台下载的头像是长方形的。原来的头像显示使用cocos的mask组件进行渲染,效率较低。我们自己实现了一个基于网格的控件,把一个圆分成n个三角形,给这些三角形的顶点分配对应的UV,从而画出一个圆形的头部。减少渲染头像时的批处理开销。  碰撞检测  CocosCreator内置的碰撞系统效率不高,没有做空间划分,所以不适合大量单元的碰撞检测。并且每一帧都需要更新collider的collisionbox。我们的游戏地图中有大量的静态物体(比如地图中的砖块、主基地、钢板等),当玩家在场景中移动时,通过移动相机来改变地图的视图,所以地图上大量静态物体的世界坐标是恒定的,它们的碰撞盒只需要计算一次。  为了解决这个问题,我们在cocos节点中添加了一个属性static,可以缓存静态节点的计算结果,避免重复计算。  对象池  游戏中的坦克、子弹、砖块等使用对象池,在进入战斗场景时有足够数量的预加载,在战斗中重复使用,避免实时对象创造与毁灭。  避免场景和节点更新  分析CocosCreator源码发现,当一个节点激活时,会触发场景的递归遍历,开销很大。  为了避免这种开销,当游戏中的物体死亡时,不会将其从场景中移除或禁用,而是会设置死亡状态,代码中不会执行相应的逻辑通过移动坐标到较远的地方处理。尽量保持帧率稳定,避免在性能曲线上出现毛刺  裁剪  当物体不在主角视野内且长时间不播放的特效和声音可以裁剪和没玩过。  模型适配  美术资源分为高、中、低三个等级,不同等级下的资源名称由规划师在资源表中配置。比赛时,根据车型和实际表现选择性能等级。  图中横坐标为时间(秒),纵坐标为FPS。可以看出FPS有了明显的提升。通过一系列优化措施,最终保证低端iphone5S基本可以满足游戏需求。  以上是《欢乐坦克大战》微信小游戏开发的总结,有兴趣的小伙伴可以一起交流哦~