Issues on Actions (FiniteTimeActions) and (RepeatForeverAction)

Hello dear people of this community, I want to ask some issues I have about Actions and hope you kindly can help me.

1st.
I need to run an AnimateAction on my Sprite
that is initialized this way:

Vector<SpriteFrame *> animFrames;
auto acc = 0;

for (int i = 0; i < 4; i++){
    auto frame = SpriteFrame::create("newPlyrSpriteSheetInverseRight.png", Rect(acc, 0, 50, 63));
    acc += 50;
    animFrames.pushBack(frame);
}

auto animation3 = Animation::createWithSpriteFrames(animFrames, 0.2f);
cocos2d::Action *inverseRightAnimation = Animate::create(animation);

inverseRightAnimation->setTag(INVERSE_RIGHTANIM);
inverseRightAnimation->retain();

so as I see in documentation Animate is a FiniteTimeAction. Need to instantly on end of this Animate, run a repeat forever Animate (no FiniteTimeAction) that is my actual IDLE animation.
Since in theory I can’t run the repeat forever on a sequence I try to do it indirectly with a callFunc and a lambda:

    runAction(Sequence::create(_inverseRightAnimation, CallFunc::create([&](){
        runAction(_IDLEAnimation->clone());
    }), nullptr));

The thing is that my callFunc is being detected well for compiler as a FiniteTimeAction I mean I can include it on my sequence but not the case for my _inverseRightAnimation, is this a bug? how can I implement it?

2nd.
I am setting tags on the Actions I initialize for stopping them later which is working correctly, if I run the action in the form:

    runAction(_IDLEAnimation);

everything goes well, but if I try this way:

    runAction(getActionByTag(IDLEANIM));

I get an assertion error on execution time that tells me the action is already added. Why is that?

The error message is correct, and it is because you’re assigning the Animate object to a variable of type Action:
cocos2d::Action *inverseRightAnimation = Animate::create(animation);

It should be either:
auto inverseRightAnimation = Animate::create(animation);
or
cocos2d::Animate* inverseRightAnimation = Animate::create(animation);

That is why the Sequence::create(...) won’t accept it, given that Action does not inherit from FiniteTimeAction, but is actually one of it’s ancestors.

Another way to handle this would be to call animation->getCurrentFrameIndex() on every update, and once it hits the last frame, stop that action, and then replace that animation with the idle animation.

If all else fails, another option is to sub-class cocos2d::Animate, and add the logic in it to provide a call back for when the animation is complete. You can then set a callback handler which you can use to do whatever you need.

That code makes no sense, because you’re getting the current action, and then setting that same action again on the same object. The assert it quite literally notifying you of that fact. Why are you even doing this? If you want to restart the animation, then one way is to set the animation into the Animate object again, since it has a function for that:

void Animate::setAnimation(cocos2d::Animation *animation)

Insist, I don’t get the error on putting the CallFunc action inside the sequence, I get the error on putting specially the inverseRightAnimation which makes no sense and I wanna know why because documentation says IntervalActions can be sequenced, this includes this type of Action “Animate”.

Thanks for this, I think this could be a solution.

I can’t implement the method that includes getCurrentFrameIndex() because I want the change of the animation to depend on a release of the touch that is why I made it RepeatForever.

I am sorry I didn’t specified that previously I stopped the action by tag, and then I try to get it by tag which refers to the ActionManager and when I stopped it I removed it from the ActionManager, that explains that I can’t execute it again trying to getting it by action but I can make it referring to the pointer which I assigned before, now it’s clearer.

You’re right, and the fix is actually in my post above. I’ve updated my previous post to make it clearer. You can set the Animate in a Sequence, but the error is because you’ve assigned the Animate to a variable of type Action.

1 Like

Thanks, I was wrongly assuming that I could call a inherited method from a base class pointer, I think I need to keep learning C++. Also I learned about how Actions are managed by the ActionManager but how could I knew before? I think the documentation misses a lot of details.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.