• cocos2dx——多段式进度条实现思路


    效果

    在这里插入图片描述

    需求描述

    1. 多段进度条,收集东西的时候,进度条增长。
    2. 无缝衔接,比如这次收集前在A,收集后要涨到B,那么A涨完了,B接着开始。
    3. 上涨的速度不一样,也就是视觉上看起来,每一段,前面慢,后面要快。

    思路

    1. 用一个数组记录每一段旧的比例
    2. 用一个数组记录每一段新的比例
    3. 用一个数值记录当前在第几段
    4. 用消息通知机制去通知下一段上涨

    这里可以选择用cocos2dx的loadingbar,但是loadingbar本质是缩放,进度条也可能会做成spine,所以选择用Layout的裁剪方法。

    这是进度条经常用的一种方法。思路就是,将进度条的node节点放置到Layout的裁剪区外,根据定时器去改变它的坐标,显示到裁剪区内,从而实现进度条上涨的动画。

    与之对应的就是loadingbar每一帧设置百分比一样。

    实现

    知道原理了,实现起来就很简单了。
    下面是关键的地方

    设置新的收集数每段的百分比

    --处理当前的stage的百分比
    function CommonProgressBarView:dealStagePercet(percentStage)
        local curPercent = 0
        for i = 1,#self.m_statgetotal do
            local leftTotalCount = self:getBeforeTotalCountByPos(i)
            if self.m_curCollectNumber <= leftTotalCount then
                self.m_progressIndex = i
                curPercent = (self.m_curCollectNumber - self:getBeforeCountByPos(i)) / self.m_statgetotal[i]
                --这里写了个算法,目的是让进度条按照规定函数进行转换
                curPercent = CommonProgressBarDef.PROGRESS_PERCENTCHANGE(curPercent,self.m_partPercentDef)
                if percentStage then
                    for j = 1,#percentStage do
                        if j < i then
                            percentStage[j] = 1
                        elseif j == i then
                            percentStage[j] = curPercent
                        else
                            percentStage[j] = 0
                        end
                    end
                end
                break
            end
        end
        return curPercent
    end
    
    • 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

    设置方向

    --设置方向
    function CommonProgressBarView:setProgressByIndex(index,percent)
        local progressInfo = self.m_progressVect[index]
        if progressInfo then
            local node = progressInfo.node
            local direction = progressInfo.direction
            local length = progressInfo.length
            if direction == CommonProgressBarDef.PROGRESS_DIRECTION.VERTICAL then
                node:setPositionY(percent * length)
            elseif direction == CommonProgressBarDef.PROGRESS_DIRECTION.VERTICALFLX then
                node:setPositionY(length - percent * length)
            elseif direction == CommonProgressBarDef.PROGRESS_DIRECTION.TRANSVERSE then
                node:setPositionX(percent * length)
            elseif direction == CommonProgressBarDef.PROGRESS_DIRECTION.TRANSVERSEFLX then
                node:setPositionX(length - percent * length)
            end
        end
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    进度条上涨的逻辑

    -- 进度条 涨的逻辑
    function CommonProgressBarView:updateCollectBarByActionByIndex(index,callBack)
        if self.m_progressBarAction then
            self:stopAction(self.m_progressBarAction)
            self.m_progressBarAction = nil
        end
        local oldPercent = self.m_statgeOldPercent[index]
        local newPercent = self.m_statgeNewPercent[index]
        self.m_progressBarAction = schedule(self,function()
            local addNumber = (self.m_partPercentSpeedConfig[index] or 0.3) * CommonProgressBarDef.PROGRESS_SPEEDFACTOR
    
            if newPercent > 1 then
                newPercent = 1
            end
            oldPercent = oldPercent + addNumber
            if oldPercent >= newPercent then
                if oldPercent > 1 then
                    oldPercent = 1
                end
                self:stopAction(self.m_progressBarAction)
                self.m_progressBarAction = nil
                oldPercent = newPercent
                --------- 消息通知 通知下检查,是下一段涨,还是结束,还是满了
                ----此处 未写----
            end
            self:setProgressByIndex(index,oldPercent)
        end,1 / 60)
    end
    
    • 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

    加速

    代码中有一段

    --这里写了个算法,目的是让进度条按照规定函数进行转换
                curPercent = CommonProgressBarDef.PROGRESS_PERCENTCHANGE(curPercent,self.m_partPercentDef)
    
    • 1
    • 2

    本质就是通过当前的比例去置换计算后的比例,保持原点,即(0,0)不变和(1,1)不变。

    类似如下的方法:

    CommonProgressBarDef.PROGRESS_PERCENTCHANGE = function(percent,status)
        if percent >= 1 or percent == 0 then
            return percent
        end
        if status == CommonProgressBarDef.PROGRESS_PERCENTKIND.NULL then
            return percent
        elseif status == CommonProgressBarDef.PROGRESS_PERCENTKIND.CIRCULAR then
            return CommonProgressBarDef.PROGRESS_SPEEDCIRCULAR(percent)
        end
        return percent
    end
    
    -- 以(1,0)为圆心,1为半径的圆的四分之一
    CommonProgressBarDef.PROGRESS_SPEEDCIRCULAR = function(percent)
        if percent >= 1 or percent == 0 then
            return percent
        end
        local tempPercent = percent * 100
        tempPercent = math.sqrt(math.abs(2 * tempPercent - math.pow(tempPercent,2)))
        if tempPercent < 0 then
            tempPercent = math.abs(tempPercent)
        end
        return tempPercent / 100
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    最后

    其实知道大致的方法,不管是creator也好,还是其他的也好,都七七八八了。

  • 相关阅读:
    指令格式学习
    【牛客 - 剑指offer】JZ3 数组中重复的数字 两种思路 Java实现
    解读MySQL 8.0数据字典的初始化与启动
    『Bug挖掘机 - 赠书02期』|〖Effective软件测试〗
    Nacos适配达梦
    C#是否应该限制链式重载的设计模式?
    探究什么是框架呢
    操作系统概念 线程调度
    SpringBoot+vue开发记录(二)
    基于jsp+mysql+ssm大学本科考研服务系统-计算机毕业设计
  • 原文地址:https://blog.csdn.net/canjiangmengyuan/article/details/127689410