金币落袋效果

效果演示

金币从初始点散开然后逐个飞落到指定的位置,这是游戏里面很常用的一个动画,效果如下

金币落袋

实现思路

要实现这个效果,我们已知三个条件,分别是起点位置,终点位置,金币个数。

生成金币位置

金币散开的位置看起来很随机,但是经过我们的拆解,其实它的第一步是先生成一个标准的圆。假设我们现在是8个金币,我们知道起点的坐标,如何求这8个金币的散开位置呢,这其实是一个数学问题。
8个金币平分一个圆,每个金币夹角是360度 / 8 = 45度,假设圆的半径r是确定的,我们又知道圆心的坐标,结合三角函数我们就能够很轻易算出每个金币的位置。
fly_gold_circle_0

当我们拥有每一个金币的标准位置之后,再给它们每个的位置叠加一个随机偏移,这样子他们的位置看起来就是围绕着起点做随机分布

以上代码如下

/**
 * 以某点为圆心,生成圆周上等分点的坐标
 *
 * @param {number} r 半径
 * @param {cc.Vec2} pos 圆心坐标
 * @param {number} count 等分点数量
 * @param {number} [randomScope=80] 等分点的随机波动范围
 * @returns {cc.Vec2[]} 返回等分点坐标
 */
getCirclePoints(r: number, pos: cc.Vec2, count: number, randomScope: number = 60): cc.Vec2[] {
  let points = [];
  let radians = (Math.PI / 180) * Math.round(360 / count);
  for (let i = 0; i < count; i++) {
    let x = pos.x + r * Math.sin(radians * i);
    let y = pos.y + r * Math.cos(radians * i);
    points.unshift(cc.v3(x + Math.random() * randomScope, y + Math.random() * randomScope, 0));
  }
  return points;
}

金币落袋

拆分效果可以看到,金币落袋的过程中还有先后的顺序,我们在实现的时候先计算一下每个金币到袋子的距离,然后做个排序,让距离袋子近的金币先执行进袋的动画,远的后执行。


代码的实现如下:

goldNodeList.sort(node => node.dis);

goldNodeList.forEach((node, idx) => {
    node.gold.runAction(cc.sequence(
        cc.moveTo(0.3, node.startPoint),
        cc.delayTime(idx * 0.03),
        cc.moveTo(0.6, node.endPoint),
        cc.callFunc(() => {
            this.goldPool.put(node.gold);
        })
    ))
});

效果预览

源码获取请点击查看原文,长按二维码查看效果:point_down:

ewm

我是异名,你的阅读是我的动力,其他文章链接:

源码地址https://github.com/ifengzp/cocos-awesome/

24赞

赞一个!

mark

mark 1

markmark

支持一下~~

赞一个,不错。

你出的东西都好精啊~再次mark~

大佬有没有金币飞到终点的路径 是一个弧度的 代码~
我想做个伸手党:joy:

我直接用jumpTo调整高度正负来实现:14:不过并不是很圆滑

如果是起始点固定的话,你可以通过动画编辑器来编辑position的路径,各种弧度和轨迹你都可以调;如果是起始点不固定,目前飞舞的轨迹好像也已经能够达到我们的需求了?为甚还要强调带起一个弧线呢

这个实现其实是把金币生成,散开,初始点封装在一起。在一些随机的金币掉落场景里面是可以直接使用的,你自己去手动调节位置其实是不可复用的,而且效率很低,也无法做到在随机的初始点处生成金币

带弧线好看~
我目前用了样基线条,贝塞尔曲线~
大佬没有现成的,我就只能自己动手撸了····

可以使用赛贝尔曲线
var bezier = [cc.v2(0, windowSize.height / 2), cc.v2(300, -windowSize.height / 2), cc.v2(300, 100)];
var bezierTo = cc.bezierTo(2, bezier);

:grin: 我写了一个简单的 正态分布 掉落。

详细说明

2赞

谢谢····已经搞定了····

let x = pos.x + r * Math.sin(radians * i); let y = pos.y + r * Math.cos(radians * i);
这里sin和cos是不是反了?

我提个小小的建议····
增加的随机便宜全部是正直,也就是全部向右上偏移了~
可以稍微改进一丢丢····

mark!