cocos2d-x 滚动数字label

费秦迟
2023-12-01

游戏中有时候需要滚动计数显示,比如添加金币从100滚动显示到9999,这里封装一个动作,直接传入label即可,方便使用。
使用时调用UtilsLabel里面的方法即可。

//
//  UtilsLabel.hpp
//  ActionLabel
//
//  Created by xujw on 16/3/7.
//
//

#ifndef UtilsLabel_h
#define UtilsLabel_h

#include <stdio.h>
#include "cocos2d.h"
USING_NS_CC;

typedef enum labelFormat
{
    kNormal = 0,
    kSeparator = 1  //有逗号分隔,比如100,200,300
}kLabelFormat;

class UtilsLabel
{
public:
    //maxWidth=0表示不对label进行缩放
    static void setLabelValueWithFormat(Label*label,long long value,float maxWidth=0,kLabelFormat format =kNormal);

    static void runLabelValueTo(Label*label,long long toValue,float duration,float width=0,kLabelFormat format=kNormal);

    static void runLabelValueToValue(Label*label,long long startValue,long long toValue,float duration,float width=0,kLabelFormat format=kNormal);

};
#endif /* UtilsLabel_h */
//
//  UtilsLabel.cpp
//  ActionLabel
//
//  Created by xujw on 16/3/7.
//
//

#include "UtilsLabel.h"
#include "ActionLabelValueTo.h"

void UtilsLabel::setLabelValueWithFormat(cocos2d::Label *label, long long value, float maxWidth,kLabelFormat format)
{
    std::string strValue = StringUtils::format("%lld",value);
    if (format == kSeparator)
    {
        //需要千位分隔符
        if (strValue.length() > 3)
        {
            int count = strValue.length() / 3;
            if (strValue.length() % 3 == 0)
            {
                count = count - 1;
            }
            for (int i=0; i<count; i++)
            {
                strValue.insert(strValue.length()-((i+1)*3+i), ",");
            }
        }
        label->setString(strValue);
    }
    else
    {
        label->setString(StringUtils::format("%lld",value));
    }

    //需要缩放
    if (maxWidth > 0)
    {
        float s = maxWidth/label->getContentSize().width;
        if (s<1.0)
        {
            label->setScale(s);
        }
    }
    else
    {
        label->setScale(1.0f);
    }
}

void UtilsLabel::runLabelValueTo(cocos2d::Label *label, long long toValue, float duration, float width, kLabelFormat format)
{
    label -> stopAllActions();
    long long startValue = 0;
    if (format == kSeparator)
    {
        //当前值可能是有逗号分隔的,将233.233.233转为233233233
        std::string str = label->getString();
        int len = str.length();
        std::string strVlaue = "";
        for (int i=0; i<len; i++)
        {
            if (str.at(i) != ',')
            {
                strVlaue += str.at(i);
            }
        }
        startValue = atoll(strVlaue.c_str());
    }
    else
    {
        startValue = atoll(label->getString().c_str());
    }

    if (duration <= 0)
    {
        setLabelValueWithFormat(label, toValue,width,format);
    }
    else
    {
        label->runAction(ActionLabelValueTo::create(duration, startValue, toValue,width,format));
    }
}

void UtilsLabel::runLabelValueToValue(Label*label,long long startValue,long long toValue,float duration,float width,kLabelFormat format)
{
    if (duration <= 0)
    {
        setLabelValueWithFormat(label, toValue,width,format);
    }
    else
    {
        label->runAction(ActionLabelValueTo::create(duration, startValue, toValue,width,format));
    }
}

//
//  ActionLabel.hpp
//  ActionLabel
//
//  Created by xujw on 16/3/7.
//
//  当label数值是数字时进行滚动效果,比如从1滚动到100

#ifndef ActionLabel_h
#define ActionLabel_h

#include <stdio.h>
#include "cocos2d.h"
#include "UtilsLabel.h"
USING_NS_CC;

class ActionLabelValueTo:public ActionInterval
{
public:
    ActionLabelValueTo();
    ~ActionLabelValueTo();
    static ActionLabelValueTo* create(float duration,long long startValue,long long endValue,float width=0,kLabelFormat format=kNormal);
    bool initWithDuration(float duration,long long startValue,long long endValue,float width,kLabelFormat format);
    virtual void startWithTarget(Node *target) override;
    virtual void update(float time) override;

private:
    long long _startValue;
    long long _endValue;
    long long _delayValue;
    float _maxWidth;
    kLabelFormat _labelFormat;
};

#endif /* ActionLabel_h */
//
//  ActionLabel.cpp
//  ActionLabel
//
//  Created by xujw on 16/3/7.
//
//

#include "ActionLabelValueTo.h"

ActionLabelValueTo::ActionLabelValueTo()
:_startValue(0)
,_endValue(0)
,_delayValue(0)
,_maxWidth(0)
,_labelFormat(kNormal)
{}
ActionLabelValueTo::~ActionLabelValueTo()
{}

ActionLabelValueTo* ActionLabelValueTo::create(float duration, long long startValue, long long endValue,float maxValue,kLabelFormat format)
{
    auto lvt = new(std::nothrow) ActionLabelValueTo();
    if (lvt && lvt->initWithDuration(duration, startValue, endValue,maxValue,format ))
    {
        lvt->autorelease();
        return lvt;
    }
    CC_SAFE_DELETE(lvt);
    return nullptr;
}

bool ActionLabelValueTo::initWithDuration(float duration, long long startValue, long long endValue,float maxWidth,kLabelFormat format)
{
    if (!ActionInterval::initWithDuration(duration))
    {
        return false;
    }

    _startValue = startValue;
    _endValue = endValue;
    _labelFormat = format;
    _maxWidth = maxWidth;

    return true;
}
void ActionLabelValueTo::startWithTarget(cocos2d::Node *target)
{
    ActionInterval::startWithTarget(target);
    _delayValue = _endValue - _startValue;
}
//time is 0 to 1
void ActionLabelValueTo::update(float time)
{
    if (getTarget())
    {
        Label *label = dynamic_cast<Label*>(getTarget());
        CCASSERT(label, "target must be a Label!");
        long long v = (long long)(_delayValue * (double)time);
        long long curValue = _startValue + v;

        //简易单独使用动作可以用下面代码
//        std::string strValue = StringUtils::format("%lld",curValue);
//        label->setString(strValue);

        UtilsLabel::setLabelValueWithFormat(label, curValue,_maxWidth,_labelFormat);
    }
}
 类似资料: