Need to pause and resume a specific action/schudual for a specific node

Need to pause and resume a specific action/schudual for a specific node

Currently, I can only pause and resume all the actions/schuduals at once for a apecific node.

Tks a lot:)

  1. Give the action a tag: myAction->setTag(1);
  2. Pause the action with the specific tag and pause it: myNode->getActionByTag(1)->pause();

Edit: pausing an action was mixed with pausing an animation.

See answer below.

I need to pause one specific action of a Sprite node (a RepeatForever MoveBy. It has other actions too like ScaleTo and EaseElasticOut, but I only need to pause the RepeatForever MoveBy action). When I try this approach: sprite->getActionByTag(1)->pause(); the pause() function isn’t there. Any suggestions?

pause() is a function of a node. Actions are derived from Node. If it’s not callable, you did not return a Node.

Edit: Actions do not derive from Node.
See answer below.

Did you do some casting?
What is your error?
Post your code.

This code is in the constructor of the object:

    if ( isItScrolling ) {
    auto moveDown = MoveBy::create( COMMON_SCROLL_SPEED, Vec2( 0, -visibleSize.height ) );
    auto repeatMoveDown = RepeatForever::create( moveDown );
    repeatMoveDown->setTag( kTagScrollers );
    sprite->runAction( repeatMoveDown );
} else {
    auto moveDown = MoveBy::create( COMMON_SCROLL_SPEED, Vec2( 0, -visibleSize.height ) );
    auto repeatMoveDown = RepeatForever::create( moveDown );
    repeatMoveDown->setTag( kTagScrollers );
    sprite->runAction( repeatMoveDown );
    sprite->getActionByTag( kTagScrollers )->pause();
}

Error: No member named ‘pause’ in ‘cocos2d::Action’

Then the idea is to resume the MoveBy action later when the game is scrolling.

Ah sorry. Action does not inherit Node.

You have to call it through the director functions.

If you have access to the action pointer directly:

Director::getInstance()->getActionManager()->pauseTarget(repeatMoveDown);

If you don’t have direct access:

Director::getInstance()->getActionManager()->pauseTarget(sprite->getActionByTag(kTagScrollers));

Edit: Silly me, the call takes a Node, not an Action. Third try below :blush:

Thanks for the fast replies, but I still cannot get it to work.

This: Director::getInstance()->getActionManager()->pauseTarget(repeatMoveDown); gives med this error: "Cannot initialize a parameter of type 'cocs2d::Node * with an lvalue of type ‘cocos2d::RepeatForever *’.

This: Director::getInstance()->getActionManager()->pauseTarget(sprite->getActionByTag(kTagScrollers)); gives med the error: “Cannot initialize a parameter of type ‘cocos2d::Node *’ with an rvalue of type 'cocos2d::Action *”

Ah I hate the API/beahviour inconsistency between cocos2d-x actions and cocos2d-x armatures and Spine animations.

Sorry, I mistook something between those. Had to look up the implementation :blush:
Things got a little mixed as I dropped 90% of actions in favor of animations.

The Director works on all the actions on a Node. So the pauseTarget call takes a Node, not an animation. Because of this, you can only stop all running actions on a Node. Pausing a specific function is not possible. You can only stop different actions on a Node's child.
Pausing a Node just pauses the update call for it, so every action is affected.

You would need to store the state(parameters) of the action you want to pause, stop the animation and create the action with the stored state(parameters) on “resuming”.

Another approach would be to run the action only once with a callback to the action itself. Wrap it into a function, which checks a param, to create the action again.
If the param is not set, don’t call it again. This will create a “repeat forever” manually.

Check out this post: http://stackoverflow.com/questions/27523930/pause-a-specific-action-on-sprite

void MySprite::jumpForever()
{
    if (!pause)
    {
         auto jump = JumpBy::create(0.5, Vec2(0, 0), 100, 1);
         auto endCallback = CallFuncN::create(CC_CALLBACK_1(MySprite::jumpForever,this));
         auto seq = Sequence::create(jump, endCallback, nullptr);
         runAction(seq);
    } 
}

pause: set pause to true
resume: set pause to false and call jumpForever again.

But as your action is only an autoscroller, I suggest using a scheduler. A scheduler can be paused and resumed. No actions required.

1 Like

Thanks for clearing this up. I ended up using this approach instead:

if ( isItScrolling ) {
    sprite->setPosition( Vec2( sprite->getPosition().x, sprite->getPosition().y - ( COMMON_SCROLL_SPEED_DT * visibleSize.height * dt ) ) );
}

Now I can stop the movement of the sprite without pausing the other actions on it.