Cocos2d-x 3.4 Action管理(ActionManager)总结

本文详细介绍了Cocos2d-x的ActionManager如何管理并执行动作,包括不同类型的回调函数(CC_CALLBACK_0, CC_CALLBACK_1)以及如何在特定条件(如动作执行完毕、定时器触发)下控制动作的开始、停止和暂停。通过实例展示了在不同场景下如何使用ActionManager来控制多个动作的执行顺序和组合。" 103455721,8642729,Centos7 GitLab安装与卸载指南,"['GitLab', 'Linux系统管理', '服务器管理', '邮件配置']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


Cocos2d-x Action管理

动作管理类CCActionManager是一个管理所有动作的单例,工作原理是:当CCNode执行runAction时,该函数会把动作通过动作管理类的addAction函数将对象传递给CCActionManager的单例,该实例再把这个动作添加到自己的动作序列中。

动作管理单例通过定时刷新自己的update方法,在这个方法中去调用行为序列中每个动作的step(暂停的行为不会update),这些step方法再根据自身的完成进度去update或是结束行为。

实际上是由动作管理单例驱动的每个动作去更新自己的逻辑,而runAction方法只是将行为对象添加进CCActionManager的待执行队列。当节点被清除或是行为结束时,动作管理类会自动将动作从队列中删除,不需要程序员的管理。

一般情况下,不需要使用这个单例来管理动作,可以使用CCNode类的stopActionstopActionByTagstopActions等函数来管理、但是有两种情况需要使用CCActionManager类单例:

<1> 动作的执行者不是同一个节点。 <2> 需要暂停/重启活动时。


一、CC_CALLBACK_0 不带参数

auto child = Sprite::create("Images/grossini.png");

Rect r = Director::getInstance()->getOpenGLView()->getVisibleRect();

Vec2 v2 = Vec2(r.origin.x+300,r.origin.y/2+r.size.height-300);

child->setPosition(v2);

addChild(child,1);

child->runAction(RotateBy::create(1.5f,90));//顺时针旋转 90

child->runAction(Sequence::create(DelayTime::create(1.4f),FadeOut::create(1.1f),nullptr));//1.4秒后,消失

child->runAction(Sequence::create(DelayTime::create(1.4f),CallFunc::create(CC_CALLBACK_0(HelloWorld::remove,this)),nullptr));//1.4秒后,执行remove方法


void HelloWorld::remove(){

    CCLOG("bbbbbbbbbb");

}


二、CC_CALLBACK_1 带一个参数

auto child1 = Sprite::create("Images/grossini.png");

addChild(child1,0,2);

Rect r1 = Director::getInstance()->getOpenGLView()->getVisibleRect();

Vec2 v2 = Vec2(r1.origin.x+300,r1.origin.y/2+r1.size.height-300);

child1->setPosition(v2);

child1->runAction(Sequence::create(MoveBy::create(1,Vec2(150,0)),CallFuncN::create(CC_CALLBACK_1(HelloWorld::update1,this)),nullptr));

 

void HelloWorld::update1(Node* node){

    node->stopAllActions();

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

    //removeChild(node);

}


三、CC_SCHEDULE_SELECTOR先执行一个动作然后定时执行某个动作

auto child2 = Sprite::create("Images/grossini.png");

    addChild(child2,0,121);

    Rect r1 = Director::getInstance()->getOpenGLView()->getVisibleRect();

    Vec2 v2 = Vec2(r1.origin.x + 300,r1.origin.y/2 + r1.size.height -300);

    child2->setPosition(v2);

    auto action = MoveBy::create(1,Vec2(150,0));

    auto director = Director::getInstance();

    director->getActionManager()->addAction(action,child2,true);

    schedule(CC_SCHEDULE_SELECTOR(HelloWorld::unpause),3);//3秒后执行unpause方法


void HelloWorld::unpause(float dt){

         //unschedule(CC_SCHEDULE_SELECTOR(HelloWorld::unpause));

         auto node =getChildByTag(121);

         auto director = Director::getInstance();

         CCAction* action1 = CCRotateBy::create(1, 360);

         //director->getActionManager()->resumeTarget(node);

         node->runAction(action1);

}


四、执行完某个动作后停止动作

auto child2  = Sprite::create("Images/grossini.png");

    Rect r1 = Director::getInstance()->getOpenGLView()->getVisibleRect();

    Vec2 v2 = Vec2(r1.origin.x +300,r1.origin.y/2 +r1.size.height -300);

    child2->setPosition(v2);

    addChild(child2,0,111);

    auto pmove = MoveBy::create(2,Vec2(200,0));

    auto pCallback = CallFunc::create(CC_CALLBACK_0(HelloWorld::stopAction,this));

    auto pSequence = Sequence::create(pmove,pCallback,nullptr);

    pSequence->setTag(121);

    child2->runAction(pSequence);


void HelloWorld::stopAction(){

         auto sprite =getChildByTag(111);

         sprite->stopActionByTag(121);

}


五、停止所有动作,但保持某个动作

auto pmove1 = MoveBy::create(2,Vec2(200,0));

    auto pmove2 = MoveBy::create(2,Vec2(200,0));

    auto pSequenceMove = Sequence::createWithTwoActions(pmove1,pmove2);

    auto pRepeatMove = RepeatForever::create(pSequenceMove);

    pRepeatMove->setTag(111);

    auto pScale1 = ScaleBy::create(2,1.5f);

    auto pScale2 = ScaleBy::create(2,1.0f/1.5f);

    auto pSequenceScale = Sequence::createWithTwoActions(pScale1,pScale2);

    auto pRepeatScale = RepeatForever::create(pSequenceScale);

    pRepeatScale->setTag(111);

    auto pRotate = RotateBy::create(2,360);

    auto pRepeateRotate = RepeatForever::create(pRotate);

    auto pChild = Sprite::create("Images/grossini.png");

    Rect r = Director::getInstance()->getOpenGLView()->getVisibleRect();

    Vec2 v2 = Vec2(r.origin.x + 300, r.size.height -300);

    pChild->setPosition(v2);


    addChild(pChild,1,112);

    pChild->runAction(pRepeatMove);

    pChild->runAction(pRepeatScale);

    pChild->runAction(pRepeateRotate);

    this->scheduleOnce((SEL_SCHEDULE)& HelloWorld::stopAction,4);


void HelloWorld::stopAction(float time){

         auto sprite =getChildByTag(112);

         sprite->stopAllActionsByTag(111);

}


六、一段时间后执行一次某个动作

Rect r = Director::getInstance()->getOpenGLView()->getVisibleRect();

    Vec2 v2 = Vec2(r.origin.x + 300,r.size.height -300);

    auto child = Sprite::create("Images/grossini.png");

    addChild(child,0,111);

    child->setPosition(v2;

    //child->runAction(ScaleBy::create(2,2));

    auto director = Director::getInstance();

    //director->getActionManager()->pauseTarget(child);//貌似不起作用

    //child->runAction(RotateBy::create(2,360));

this->schedule(CC_SCHEDULE_SELECTOR(HelloWorld::resumeChild),8.0f);


void HelloWorld::resumeChild(float time){

    //this->unschedule(CC_SCHEDULE_SELECTOR(HelloWorld::resumeChild)); //加上这句只执行一次,否则每8秒调用一次

         auto child =getChildByTag(111);

         auto director = Director::getInstance();

         //director->getActionManager()->resumeTarget(child);//貌似不起作用

         child->runAction(RotateBy::create(2,360));

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值