在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!

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

https://www.kuokuo666.com/home/kk061.html

作者

KUOKUO众享

发布于

2023-07-11

更新于

2024-03-05

许可协议

评论