《祖玛ZUMA》分享技术思路和贝塞尔曲线细节实现,匀速加减速

背景:

这个年都没过,就开发了这一款游戏,大家都在吃吃喝喝的时候,我一个人在写代码。印证了一句话:孤独寂寞冷。

一边忍受着寂寞,一边强迫自己要坚持不能松懈,好在终于赶在上班之前弄完了。:smile:

实现思路:

首先要说一下曲线的路径,我这里所用的方法是通过一段段连接的贝塞尔曲线拼接而成,紧接着就要获取曲线上的点了,直接套用二阶贝塞尔曲线公式求得,这里贴一下曲线的原理和公式(具体细节请各位自行谷歌),如下:

二阶曲线由两个数据点(P0 和 P2),一个控制点(P1)来描述曲线状态,从而计算动点B:

这里为了实现匀速运动,需要一个求t的公式算法来达到匀速的目的,这里需要使用牛顿切线法求出近似解,同时通过牛顿切线法得到某一个点的导数,比如我的球在沿着曲线运动时,可以正常的旋转一定的角度。

关于t的推导公式,我这里借鉴了一位大神的帖子,迭代算法公式为:

L(t)函数的推导公式如下:

这样,当贝塞尔曲线的长度间距无限小时,得出的t值,也是相对于比较精确的。
来源链接:https://blog.csdn.net/linuxheik/article/details/79454663
(大神已经贴了完整的代码,可以直接参考)

有了这个,就好办了,拿到点以后,看似复杂的曲线,现在就可以看成是一条“直线”了,在直线上实现一个物体的加速度、减速度、匀速等运动,应该算很easy了。

注意:连接之后,每个连接点处,会重复一个额外的点,在代码上,需要考虑删去一个多余的重复点,简单点说,就是:去重。否则球运动到此时会多顿一下。


路径的生成,

我还特地做了一个贝塞尔曲线工具编辑器,如图:

请点击,传送门:
https://forum.cocos.com/t/topic/73416


球的运动,我这里的实现思路是将球通过一个球组对象来管理球,所有球的运动,比如加速度减速度和匀速运动都是通过球组对象来实现,然后每个球根据相互之间的“直线距离(就是一个球的直径距离)”计算依次的位置。
具体方式上,通过每帧的update方法,给球组始终保持一个不变的速度做匀速运动,也就是正常运动的速度,当需要做加速运动时,比如球刚开始冲出来时,给一个正的加速度,当需要做减速运动时,比如球收到撞击时,给一个负的加速度;如何让球慢慢回归匀速运动呢?这里我通过摩擦力系数,比如我这里使用0.9,加速度a*乘以这个系数0.9,慢慢最终使得加速度慢慢趋于0,然后回归到匀速运动状态。

发射球入轨的细节,我个人认为这里是整个游戏最复杂的地方。由于要实现球渐进式入轨,而不是瞬间“啪”的进入轨道,那么就必须要计算球的圆周路径,这样发射进来的球才能绕着接触的那个球的圆周,慢慢的绕进入轨道。

首先需要分阶段,我这里固定异步10次,也就是分10步让球慢慢的一步步进入轨道,到完成进入整个过程。每一步的逻辑是一致的。这里有大量的向量运算,我尽可能的说清楚。

a)从发射球接触到轨道球开始,计算第1步,标记为向量1:轨道球指向发射球,长度为1个球直径;
b)接着计算接触到的轨道球与下一个轨道球之间的向量,标记为向量2:从接触到的轨道球指向下一个轨道球,长度为1个球的直径;
c)向量1到向量2之间的向量,标记为向量3:从向量1指向向量2;
d)向量3长度除以10,标记为向量4,长度计算很简单,先将向量3单位化,再乘以数值1/10即可。
e)将发射球运动到向量4的位置,通过当前位置向量,做向量加向量4;
f) 依次类推,直到最终位置;

球组的合并与分拆,合并(2个球组连接之后需要合并)之后需要销毁前一个球组;分拆(1个球组在被打断了以后,需要将当前的球组1分为2)之后,产生一个新的球组插入到当前球组的前面。

以上就是整个游戏的完整思路,还有不明白的地方,请下方留言,我有时间一一为大家解答。

51赞

顶!路线生成器很nice

这里也顶一个

插旗。

可以讲解下球体运动和球体碰撞对消运动的游戏思路吗?

很棒啊,我和家人很喜欢这款祖玛的电脑版。楼主有时间把完整版实现一下,会吸引更多的用户吧。

支持下~话说icon最后一个黄球不在轨迹上差评 = =:joy:

不错,如果可以把写作思路公布下就好了

感谢支持。

如果这款游戏能赚点小钱,我就继续弄;不过目前来看,希望很渺茫。

如果能继续,我打算在完善一点东西:
1.点击青蛙,交换青蛙的前后球的位置;
2.增加双轨道路径,更刺激一点;
3.增肌穿越缝隙消除加分特效;
4.目前只有一个炸弹球,还想增加一个减速道具,一个暂停道具;
5.还可以做一个打金币;

技术上都差不多了,就是差时间和精力去弄这些,都得花时间,再说吧。:smile:

既然都这么说,源码目前我肯定不太愿意开源,那我就趁现在开始写写实现思路吧,完了后我直接编辑到主贴上去;:2:

1赞

观察入微,:+1:

百度得:
如果t变量本身线形变化的话,这条贝塞尔曲线本身的生成过程是并不是匀速的,通常都是两头快中间慢。

那肯定是的,这个根据项目实际需求来定吧。

那么如果希望线上匀速走的话,就没法用t的线性增加来算点了(比如 0 0.1 0.2 0.3~)

之前我是知道了要匀速的话,画出来的线要对称

对没错,这里还需要引入一个公式:牛顿切线法,我上面没有介绍,这块我一会把它补充上去。

跟线是否对称没有关系。

已补充。

看完后感觉运算量好大。。。怕是会卡?