[开发者心得] 如何用Tween实现曲线运动

[复制链接]
1058 |3
焦糖乳酱 An0 发表于 2023-5-12 14:18:16 | 显示全部楼层 |阅读模式
本帖最后由 焦糖乳酱 An0 于 2023-5-12 14:25 编辑


//ui贝塞尔
        InteractBtn.onPressed.add(() => {
            let pos: Type.Vector2 = Type.Vector2.zero;
            //UI上起点位置
            const pos1 = img1.position.clone();
            //UI上偏移点位置
            const pos2 = img2.position.clone();
            //ui终点位置
            const pos3 = img3.position.clone();
            new TweenUtil.Tween({ t: 0 })
                .to({ t: 1 })
                .duration(1000)
                .onUpdate(val => {
                    pos.x = (1 - val.t) * (1 - val.t) * pos1.x + 2 * val.t * (1 - val.t) * pos2.x + val.t * val.t * pos3.x;
                    pos.y = (1 - val.t) * (1 - val.t) * pos1.y + 2 * val.t * (1 - val.t) * pos2.y + val.t * val.t * pos3.y;
                    img.position = pos;
                })
                .start()

        });




//物体贝塞尔曲线
        AttackBtn.onPressed.add(() => {
            AssetUtil.asyncDownloadAsset("7809").then(val => {
                if (val) {
                    for (let i = 0; i < 100; i++) {
                        let obj: Gameplay.Particle = GameObjPool.getInstance().spawn("7809");
                        obj.ready().then(val => {
                            obj.worldScale = new Type.Vector(1.5);
                            obj.loop = true;
                            obj.play();
                            let pos = Type.Vector.zero;

                            let forwardVec: Type.Vector = Gameplay.getCurrentPlayer().character.forwardVector.clone();
                            let rightVec: Type.Vector = Gameplay.getCurrentPlayer().character.rightVector.clone();
                            let upVec: Type.Vector = Gameplay.getCurrentPlayer().character.upVector.clone();
                            //起点
                            let startPos: Type.Vector = Gameplay.getCurrentPlayer().character.worldLocation.clone();
                            //终点
                            let finalPos: Type.Vector = new Type.Vector(-591.470, -69.230, 300)//this._targetObj.worldLocation.clone();
                            //以半径500作圆,随机取一个圆上的点
                            let random = Math.random();
                            let right = rightVec.multiply((Math.random() > 0.5 ? 1 : -1) * 500 * random);
                            let up = upVec.multiply((Math.random() > 0.5 ? 1 : -1) * 500 * (Math.sqrt(1 - random * random)));
                            //偏移点
                            let midPos: Type.Vector = startPos.clone().add(forwardVec.multiply(300)).add(right).add(up);
                            new TweenUtil.Tween({ t: 0 })
                                .to({ t: 1 })
                                .duration(1000)
                                .onUpdate(val => {
                                    pos.x = (1 - val.t) * (1 - val.t) * startPos.x + 2 * val.t * (1 - val.t) * midPos.x + val.t * val.t * finalPos.x;
                                    pos.y = (1 - val.t) * (1 - val.t) * startPos.y + 2 * val.t * (1 - val.t) * midPos.y + val.t * val.t * finalPos.y;
                                    pos.z = (1 - val.t) * (1 - val.t) * startPos.z + 2 * val.t * (1 - val.t) * midPos.z + val.t * val.t * finalPos.z;
                                    obj.worldLocation = pos;
                                })
                                .delay((50 + Math.random() * 20) * (i - 1))
                                .start()
                                .onComplete(() => {
                                    GameObjPool.getInstance().despawn(obj);
                                })
                        })
                    }
                }
            })
        })



//sin曲线
        JumpBtn.onPressed.add(() => {
            //起点位置
            const pos1 = img1.position.clone();
            //终点位置
            const pos3 = img3.position.clone();
            //归一化法向量
            const line = pos1.clone().subtract(pos3);
            let vec = new Type.Vector(1, -(line.x / line.y)).normalized;

            new TweenUtil.Tween({ t: 0, pos: pos1 })
                .to({ t: 6, pos: pos3.clone() })
                .duration(1500)
                .onUpdate(val => {
                    //(7 - val.t) *
                    img.position = val.pos.clone().add(vec.clone().multiply(150 * Math.sin(val.t * Math.PI)))
                })
                .start();
        })

这里修改一下可以做个渐进效果
img.position = val.pos.clone().add(vec.clone().multiply((7 - val.t) *50 * Math.sin(val.t * Math.PI)))








回复

使用道具 举报

叽里咕噜小胡桃 发表于 2023-5-12 14:19:53 | 显示全部楼层
艾卡西亚暴雨!
回复

使用道具 举报

泪染倾城(找闺) 发表于 2023-5-12 15:39:10 | 显示全部楼层
缓动用Util.TweenUtil.Interpolation.Bezier之类的参数也可以有类似的效果
回复

使用道具 举报

清风予我 发表于 2023-5-15 09:30:01 | 显示全部楼层
搜嘎 学到了
回复

使用道具 举报

72小时热榜
2
【反馈】翻译异常
求助与反馈
16人已阅读
3
编辑器无法正常启动
求助与反馈
42人已阅读
5
邮件系统
游戏开发
72人已阅读
热门版块
快速回复 返回顶部 返回列表