首页 > 代码库 > Cocos2d-x 动作的管理之ActionManger

Cocos2d-x 动作的管理之ActionManger

前面讲过Node的动作(Action),cocos2d-x中,提供了一个ActionManger,用于管理Action的一些动作,比如停止,暂停等;
一、停止所有动作
实际上,Node节点已经有了一些简单的动作的管理,比如停止Node实例上的所有动作;

    node->stopAllActions(); //
    node->runAction(ScaleTo::create(2, 2))

调用node->stopAllActions(); 之前的所有动作都将停止,但是,它并影响后续的动作,后续的ScaleTo动作将正常执行;
二、延时执行动作

cocos2d-x中,并没有简单的使用一个接口直接指定某一个动作延时一段时间后执行,但是,这都不是问题,下面是一个延时3s执行动作的例子;

    auto grossini = Sprite::create(s_pathGrossini);
    addChild(grossini, 0, 98); // 为sprite指定一个tag
    grossini->setPosition(VisibleRect::center() );
    
    auto action = MoveBy::create(1, Vec2(150,0));

    auto director = Director::getInstance();
    director->getActionManager()->addAction(action, grossini, true);

    schedule( schedule_selector(PauseTest::unpause), 3);  // 每3秒执行一次unpause方法;

unpause方法实现

    unschedule( schedule_selector(PauseTest::unpause) ); // 停止循环执行unpause方法
    auto node = getChildByTag( 98); // 获取sprite实例
    auto director = Director::getInstance();
    director->getActionManager()->resumeTarget(node); // 开始执行动作

上面的例子通过schedule循环更新的方法,每3s执行一次,当执行的时候,就取消循环来实现动作延时执行的效果;
三、停止动作

void StopActionTest::onEnter()
{
    auto pMove = MoveBy::create(2, Vec2(200, 0));
    auto pCallback = CallFunc::create(CC_CALLBACK_0(StopActionTest::stopAction,this));
    auto pSequence = Sequence::create(pMove, pCallback, NULL);
    pSequence->setTag(kTagSequence); // 为动作指定tag

    auto pChild = Sprite::create(s_pathGrossini);
    pChild->setPosition( VisibleRect::center() );

    addChild(pChild, 1, kTagGrossini);
    pChild->runAction(Sequence::create(ScaleTo::create(3.0f,2.0f), NULL));
    pChild->runAction(pSequence);
    
}

void StopActionTest::stopAction() // 停止动作
{
    auto sprite = getChildByTag(kTagGrossini); // 通过tag获取sprite
    sprite->stopActionByTag(kTagSequence); // 停止sprite上的指定的tag的动作
}

停止Node的某一个动作简单来说,就是预先给动作指定一个tag,在要停止它的时候,通过stopActionByTag(tag)来停止它;
四、Resume动作

void ResumeTest::onEnter()
{
   
    auto pGrossini = Sprite::create(s_pathGrossini);
    addChild(pGrossini, 0, kTagGrossini);
    pGrossini->setPosition(VisibleRect::center());

    pGrossini->runAction(ScaleBy::create(2, 2));

    auto director = Director::getInstance();

    director->getActionManager()->pauseTarget(pGrossini);// @1
    pGrossini->runAction(RotateBy::create(2, 360));  
    this->schedule(schedule_selector(ResumeTest::resumeGrossini), 3.0f);
}

void ResumeTest::resumeGrossini(float time)
{
    this->unschedule(schedule_selector(ResumeTest::resumeGrossini));

    auto pGrossini = getChildByTag(kTagGrossini);
    auto director = Director::getInstance();
    director->getActionManager()->resumeTarget(pGrossini);
}

@1:在上面的代码中,pauseTarget方法调用之后,又再次调用了runAction,那它会不会先执行这个动作呢?实际上,是不会的(亲测),所以,我大胆的解释为pauseTarget之后,需要调用resumeTarget之后,才会执行Node实例自身的未完成的动作;

完!