1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| bezier(p0: cc.Vec2, p1: cc.Vec2, p2: cc.Vec2, t: number) { const p = p0 .mul(Math.pow(1 - t, 2)) .add(p1.mul(2 * t * (1 - t))) .add(p2.mul(Math.pow(t, 2))); return p; },
async bezierUniformMove(pos: cc.Vec2, mid: cc.Vec2, target: cc.Vec2, node: cc.Node, duration: number) { let samples: { t: number, len: number }[] = []; let totalLen = 0; let prev = this.bezier(pos, mid, target, 0); for (let i = 1; i <= 100; i++) { let t = i / 100; let pt = this.bezier(pos, mid, target, t); let d = prev.sub(pt).mag(); totalLen += d; samples.push({ t, len: totalLen }); prev = pt; }
const getTByLen = (curLen: number) => { for (let i = 0; i < samples.length; i++) { if (samples[i].len >= curLen) { // 线性插值 let prev = samples[i - 1] || { t: 0, len: 0 }; let ratio = (curLen - prev.len) / (samples[i].len - prev.len); return prev.t + (samples[i].t - prev.t) * ratio; } } return 1; }
await asyncMgr.tween(cc.tween(node).to(duration, { position: target }, { progress: (start, end, current, ratio) => { const cl = totalLen * ratio; const t = getTByLen(cl); const result = this.bezier(pos, mid, target, t); return result; } })) }
|