在CocosCreator的3.x版本中实现贝塞尔曲线

使用环境参考

CocosCreator v3.7.3

前情提要

在之前的 2.x 版本中,CocosCreator 关于贝塞尔曲线是内置了 API,可以让节点动画直接使用。但在升级到 tween 实现后,灵活了但没有了现成的贝塞尔曲线的实现方法。需要自己实现一下:

二次贝塞尔曲线(一个控制点的),为了方便观察,我用绘图组件示意了一下路径

import { _decorator, Component, Graphics, Node, tween, v3, Vec3 } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('BTest1')
export class BTest1 extends Component {
    @property(Graphics) graphics: Graphics = null;
    @property(Node) box: Node = null;

    start() {
        // 绘制路径做对比
        this.graphics.moveTo(0, 0);
        this.graphics.quadraticCurveTo(200, 300, 200, 200);
        this.graphics.stroke();

        // 三维空间的缓动
        const quadraticCurve = (t: number, p1: Vec3, cp: Vec3, p2: Vec3, out: Vec3) => {
            out.x = (1 - t) * (1 - t) * p1.x + 2 * t * (1 - t) * cp.x + t * t * p2.x;
            out.y = (1 - t) * (1 - t) * p1.y + 2 * t * (1 - t) * cp.y + t * t * p2.y;
            out.z = (1 - t) * (1 - t) * p1.z + 2 * t * (1 - t) * cp.z + t * t * p2.z;
        }

        const startPos = v3(0, 0, 0);
        const controlPos = v3(2, 3, 0);
        const endPos = v3(2, 2, 0);

        const tempVec3 = v3();
        
        tween(this.box).to(3, { position: endPos }, { onUpdate: (target, ratio) => {
            quadraticCurve(ratio, startPos, controlPos, endPos, tempVec3);
            this.box.setPosition(tempVec3);
        }}).start();
    }
}

接下来是两个控制点的,这个三次贝塞尔的计算公式 CocosCreator 进行了内置,不过是一维的,搞成三维:

import { _decorator, bezier, Component, Graphics, Node, tween, v3, Vec3 } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('BTest1')
export class BTest1 extends Component {
    @property(Graphics) graphics: Graphics = null;

    @property(Node) box: Node = null;

    start() {
        // 绘制路径做对比
        this.graphics.moveTo(0, 0);
        this.graphics.bezierCurveTo(80, 400, 200, 50, 200, 200);
        this.graphics.stroke();

        // 三维空间的缓动
        const bezierCurve = (t: number, p1: Vec3, cp1: Vec3, cp2: Vec3, p2: Vec3, out: Vec3) => {
            out.x = bezier(p1.x, cp1.x, cp2.x, p2.x, t);
            out.y = bezier(p1.y, cp1.y, cp2.y, p2.y, t);
            out.z = bezier(p1.z, cp1.z, cp2.z, p2.z, t);
        }

        const startPos = v3(0, 0, 0);
        const controlPos1 = v3(0.8, 4, 0);
        const controlPos2 = v3(2, 0.5, 0);
        const endPos = v3(2, 2, 0);

        const tempVec3 = v3();
        
        tween(this.box).to(3, { position: endPos }, { onUpdate: (target, ratio) => {
            bezierCurve(ratio, startPos, controlPos1, controlPos2, endPos, tempVec3);
            this.box.setPosition(tempVec3);
        }}).start();
    }
}
总结

将以上方法封装到自己的 Util 中就可以愉快滴使用啦!

我是阔阔,一位喜欢研究的程序员!

个人网站:www.kuokuo666.com

2023!Day Day Up!
可以愉快滴使用啦!

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KUOKUO众享

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值