滚动吧,数字

朋友有个需求关于金币滚动效果,网上也有很多教程;但多不太符合他的需求,所有利用空余时间帮他做了一个通用组件。

效果图如下:
1、按照次数和速度进行,对应的滚动效果。
2、缓动效果可以根据自己的情况进行修改。
项目地址:https://gitee.com/songhuiyuan/utility.git
在这里插入图片描述

一、节点视图如下:

在这里插入图片描述

二、思路

  • 减少控制参数,越少越好,这里有三种
    1、初始值
    2、控制参数(滚动次数和滚动速度)
    3、目标值
  • 滚动次数
    1、次数小于等于0的时候,只从初始值滚动到目标值(缓动值可以自己去跳这个)
    2、次数大于0的时候,分为加速阶段,匀速阶段、减速阶段;我们滚动的次数是控制匀速阶段的。(根据加速阶段最后两帧的位置计算出速度,匀速就按照这个速度进行滚动)。当然可以自动去改动一下达到自己的次数的效果。
  • Rolling接口
    1、initValue初始值
    2、setParam设置控制参数
    3、rollToValue滚动函数调用
    关于Test.ts中的代码仅仅测试用。没什么意义。

三、代码如下:

Rolling.ts


const { ccclass, property } = cc._decorator;

@ccclass
export default class Rolling extends cc.Component {
    /**当前数字 */
    private m_curNum: number = 0;
    /**字体高度 */
    private m_fontHeight: number = 0;
    /**开始位置 */
    private m_startPoint: cc.Vec2 = cc.v2(0, 0);
    /**单个个数 */
    private m_singleNum: number = 0;
    /**双个个数 */å
    private m_doubleNum: number = 0;
    private m_isRollIng: boolean = false;

    /**轮训次数 */
    private m_rollCounts: number = 0;
    /**滚动速度 */
    private m_rollSpeed: number = 300;

    private roolNode: cc.Node = null;

    onLoad() {
        this.roolNode = this.node;
    }

    start() {
        this.roolNode.x = this.m_startPoint.x;
        this.roolNode.y = this.m_startPoint.y;
        this.m_singleNum = this.roolNode.childrenCount / 2;
        this.m_doubleNum = this.roolNode.childrenCount;
        this.m_fontHeight = this.roolNode.height / this.roolNode.childrenCount;
    }

    public initValue(num: number) {
        this.m_curNum = num;
        this.roolNode.y = num * this.m_fontHeight;
    }

    public setParam(rollCount: number, rollSpeed: number) {
        this.m_rollCounts = rollCount;
        this.m_rollSpeed = rollSpeed;
    }

    public async rollToValue(num: number) {
        let tempNum: number = num;
        if (this.m_isRollIng) { return };
        if (tempNum < 0 || tempNum > this.m_singleNum) { return };
        this.m_isRollIng = true;
        if (num < this.m_curNum) {
            num += 10;
        }
        //到目标值长度和单次轮训长度
        let distance1: number = (num - this.m_curNum) * this.m_fontHeight;
        let distance2: number = this.m_singleNum * this.m_fontHeight;
        let time: number;
        if (this.m_rollCounts > 0) {
            time = await this.rollAccelerateAction(distance2) as number;
            time = await this.rollUniformityAction(distance2, time) as number;
            time = await this.rollDecelerateAction(distance1, num, tempNum) as number;
            this.m_isRollIng = false;
            console.log('-----执行完毕----');
        }
        else {
            if (tempNum == this.m_curNum) { return };
            time = distance1 / this.m_rollSpeed;
            cc.tween(this.roolNode)
                .by(time, { position: new cc.Vec3(0, distance1, 0) }, { easing: 'quartInOut' })
                .call(() => {
                    this.initValue(tempNum);
                    this.m_isRollIng = false;
                })
                .start();
        }
    }

    /**加速阶段 */
    private rollAccelerateAction(distance: number) {
        let array: number[] = [];
        let time: number = distance / this.m_rollSpeed;
        return new Promise((resolve, reject) => {
            cc.tween(this.roolNode)
                .by(time, { position: new cc.Vec3(0, distance, 0), }, {
                    easing: 'quartIn',
                    onUpdate: (target: cc.Vec3, ratio: number) => {
                        array.push(target.y);
                    }
                })
                .call(() => {
                    this.initValue(this.m_curNum);
                    let value = array[array.length - 1] - array[array.length - 2];
                    let speed = value / (1 / array.length);
                    resolve(distance / speed);
                })
                .start();
        });
    }

    /**匀速阶段 */
    private rollUniformityAction(distance: number, time: number) {
        let count: number = 0;
        return new Promise((resolve, reject) => {
            cc.tween(this.roolNode)
                .by(time, { position: new cc.Vec3(0, distance, 0), })
                .call(() => {
                    this.initValue(this.m_curNum);
                    count++;
                }).union().repeat(this.m_rollCounts)
                .call(() => {
                    resolve(null);
                    console.log(count);
                })
                .start();
        });
    }

    /**减速阶段 */
    private rollDecelerateAction(distance: number, num: number, tempNum: number) {
        let time: number = distance / this.m_rollSpeed;
        return new Promise((resolve, reject) => {
            cc.tween(this.roolNode)
                .by(time, { position: new cc.Vec3(0, distance, 0) }, {
                    easing: 'quartOut'
                })
                .call(() => {
                    this.initValue(tempNum);
                    resolve(null);
                })
                .start();
        });
    }
}



Test.ts//测试代码

@ccclass
export default class NewClass extends cc.Component {
    private rollScrs: Rolling[] = null;
    start () {
        let newNode = cc.find('New Node', this.node);
        if(newNode) {
            this.rollScrs = newNode.getComponentsInChildren(Rolling) || [];
        }
       
    }


    callBack() {
        this.scheduleOnce(() => {
          
            this.rollScrs[0] && this.rollScrs[0].initValue(0);
            this.rollScrs[0] && this.rollScrs[0].setParam(0,380);
            this.rollScrs[0] && this.rollScrs[0].rollToValue(6);
            this.rollScrs[1] && this.rollScrs[1].initValue(2);
            this.rollScrs[1] && this.rollScrs[1].setParam(0,380);
            this.rollScrs[1] && this.rollScrs[1].rollToValue(0);

            this.rollScrs[2] && this.rollScrs[2].initValue(0);
            this.rollScrs[2] && this.rollScrs[2].setParam(2,380);
            this.rollScrs[2] && this.rollScrs[2].rollToValue(6);
            this.rollScrs[3] && this.rollScrs[3].initValue(2);
            this.rollScrs[3] && this.rollScrs[3].setParam(2,380);
            this.rollScrs[3] && this.rollScrs[3].rollToValue(0);
        }, 2)
    }
    // update (dt) {}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值