I asked in SO, but no responses so I'm posting here since it's probably more relevant here.

EDIT: SO question closed.

I'm trying to tween primitive data-types the way Action tweens position to create movement. The main reason is to take advantage of the easing functions, rather than hand-code all the easing. This is helpful when implementing things like tweening money counter values (When the teller's display goes ka-ching, you can see the number tween towards the final value.)

Is there a way to directly apply Action or some variant of this onto datatypes like int or float?

Or do I have to cheat by keeping a Node, apply the Action onto the node's property, and read the property? (I'd rather not do this)

  • \$\begingroup\$ Why don't you chain one of the already existing easing functions with move function? something like: EaseSineIn::create(MoveBy::create(Vec2(x,y), time))? \$\endgroup\$
    – Ali1S232
    May 11, 2016 at 8:16
  • \$\begingroup\$ The Move actions apply only to the Node's position. What I want to do is to apply it to other data-types as far as possible. Like say I have a money variable: int money = 1000; I want to be able to 'animate' my money variable to 2000. How can I do that while taking advantage of the existing Action/Easing system? \$\endgroup\$
    – Mark Ang
    May 11, 2016 at 10:45

2 Answers 2


The base idea is to chain Ease Actions with your normal tween action. Ease action basically changes the flow of time for it's inner action; So by implementing a simple/linear action, and chaining it with an ease action, you'll end up with the ease function you originally intended.

As for the tweening. Let's say you want an object to change, there are two ways you can manipulate custom variables through time:

  1. Through ActionTweenDelegate: You have to create a subclass of Node, which also implements ActionTweenDelegate. You'll then have to implement updateTweenAction (float value, const char *key). In that function you simple do what ever you want to do (e.g. increase the player's money). Note that value is a number between 0 and 1.
  2. Through creating a new action: You'll have to create a subclass of FiniteTimeAction, and override update function. Despite the name, the input is not really the action time but a progress indicator between 0 and 1. Again you don't have to worry about easing at all, and just have to implement a linear modification function; The rest is up to ActionEase class chained to your action.

here is how i'm doing it in my score scene:

auto score = Label::createWithTTF("Score : 0", MY_FONT_NAME, 18);
score->enableOutline(Color4B::ORANGE, 1);

// increment score
score->schedule([this, score](float dt) {
    int initialValue = 0;
    int finalValue = currentLvScore;
    static float duration = 4.f;
    static float timeElapsed = 0.f;

    timeElapsed += dt;
    float prograss = timeElapsed / duration;

    int val = MathUtil::lerp(initialValue, finalValue, prograss);
    score->setString("Score : " + std::to_string(val));

    if (timeElapsed >= duration)
        timeElapsed = 0.f;
        score->setString("Score : " + std::to_string(currentLvScore));

}, 0.f, CC_REPEAT_FOREVER, 2.0f, "CountTo");

Edit: a much cleaner way to do it would be using ActionFloat.

    void ::onEnter() {

        auto lbl = Label::createWithTTF("0", "fonts/Marker Felt.ttf", 12.f);

        // animate float from 0 to 100 in 5 sec
        auto actionfloat = ActionFloat::create(5, 0, 100, [=](float value) {


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .