新作「 苏打世界 」已经上架AppStore,并在首页被大屏推荐。上架伊始便颇受玩家喜爱,目前已经收获大量玩家的五星好评,欢迎大家前去下载试玩。
本文将介绍游戏内的灌装系统是如何实现,最后将附上参考资料以供读者们阅读和研究。不会有具体代码,只讲思路和方法。
在「苏打世界」里,一个很重要的日常任务便是生产苏打。由于产品汪提姆绿需要尽可能的去模拟真实的苏打灌装,比如苏打灌满后溢出和未灌满时水面的波澜起伏等,这也导致用动画来模拟实现是不可能的。
所以便只能去寻找一个支持流体功能的2D物理引擎,并将其移植到我们开发采用的Cocos2d-x + Lua的游戏框架中。
当接到这个需求后,我便联想到了Google的 LiquidFun 。
由于LiquidFun支持JavaScript,这也非常方便我们快速验证原型,即LiquidFun到底是否合适我们的游戏。
对LiquidFun的testbed修修改改后,我快速的建立一个灌汽水的网页版 原型 。同事们看完觉得还可以,便开始了将LiquidFun移植到游戏的工作。
LiquidFun依赖于2D物理引擎Box2d,可以认为其是Box2d的加强版,比原先的Box2d增加了流体粒子功能。
我们游戏采用的是Cocos2d-x+Lua的框架,所以问题变成了:如何整合LiquidFun到Cocos2d-x中,并绑定其常用API到Lua中,使游戏逻辑可以操控汽水的灌装,隐藏,销毁和回收。
将这个复杂的任务分解后,大致如下:
关于LiquidFun的移植工作,已经有先驱帮我们趟坑了。Cocos2d的作者Retro在其博客中详细阐述了: 如何将LiquidFun移植到Cocos2d-x ,以及 如何利用metaballs技术来渲染粒子使其看起来更像流体 。
读者不妨先去阅读以上的两篇文章,花点时间,搞懂每一步的目的和原因。
简而言之,Retro在Part1所做的工作是将LiquidFun的每个流体粒子在物理世界的坐标转换到Cocos2d-x的绘制坐标中,然后用 GL_POINTS
命令将粒子绘制成一个个的小点显示到屏幕上。
在Part1内,我们已经完成了LiquidFun对Cocos2d-x的C++层的移植工作。但是仅仅显示一个个白色的小点是不够的,因为这样看起来不像流体而比较像沙子。
接下来在Part2中,Retro引入了一张中间圆形实心,四周趋于透明的纹理代表一个粒子,利用一个透明度阀,将此透明度(例如0.01)以下的全部显示为全透明,而之上都显示为一个纯色。然后用一个RenderTexture去实现整个Shader的绘制,最后将其显示在屏幕上。当两个粒子很临近时,可以看出一个不规则的融合形状,这个技术就是最基础的 metaballs 。
由于Cocos2d-x没有对Box2d进行tolua绑定,所有绑定的工作需要从零开始一遍。
原先本想采用Cocos 3.x引入的ini格式的配置进行绑定,后来发现不太现实,因为有太多的结构体需要进行绑定到Lua。
所以只好回归Cocos 2.x时代的pkg绑定。关于如何进行pkg绑定的方法,不是本文关心的内容。因为基本都是把C++头文件按照指定的规则转译为pkg文件的体力活。
我曾经在2.x时代因为极度痛恨这种手工方式而写了一个 Lua脚本 来进行自动转译,这个脚本现放于 Github 中,年久失修,可能有坑需要手填,慎用!
这基本是个体力活,为了大家移植方便,不再趟坑,我已经将转译好的pkg文件和tolua后的C++文件上传到 Github的仓库 中,大家可按照MIT协议进行下载使用。
一张图让你明白,其实我们后面是真的在 灌 汽水!
if...else...
分支判断 precision lowp float;