Cocos2d-x Action管理
动作管理类CCActionManager是一个管理所有动作的单例,工作原理是:当CCNode执行runAction时,该函数会把动作通过动作管理类的addAction函数将对象传递给CCActionManager的单例,该实例再把这个动作添加到自己的动作序列中。
动作管理单例通过定时刷新自己的update方法,在这个方法中去调用行为序列中每个动作的step(暂停的行为不会update),这些step方法再根据自身的完成进度去update或是结束行为。
实际上是由动作管理单例驱动的每个动作去更新自己的逻辑,而runAction方法只是将行为对象添加进CCActionManager的待执行队列。当节点被清除或是行为结束时,动作管理类会自动将动作从队列中删除,不需要程序员的管理。
一般情况下,不需要使用这个单例来管理动作,可以使用CCNode类的stopAction、stopActionByTag和stopActions等函数来管理、但是有两种情况需要使用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(CallFunc::create(CC_CALLBACK_0(HelloWorld::remove,this)),nullptr));//1.4秒后,执行remove方法
void HelloWorld::remove(){
CCLOG("bbbbbbbbbb");
}
二、CC_CALLBACK_1 带一个参数
auto child1 = "Images/grossini.png");
addChild(child1,2);
Rect r1 = Director::getInstance()->getOpenGLView()->getVisibleRect();
Vec2(r1.origin.x+300,r1.origin.y/2+r1.size.height-300);
child1->setPosition(v2);
child1->runAction(MoveBy::create(1,175); font-family:新宋体; font-size:9.5pt">Vec2(150,0)),175); font-family:新宋体; font-size:9.5pt">CallFuncN::create(CC_CALLBACK_1(HelloWorld::update1,nullptr));
void HelloWorld::update1(Node* node){
node->stopAllActions();
node->runAction(ScaleTo::create(2,2));
//removeChild(node);
}
三、CC_SCHEDULE_SELECTOR先执行一个动作然后定时执行某个动作
auto child2 = "Images/grossini.png");
addChild(child2,121);
Director::getInstance()->getOpenGLView()->getVisibleRect();
Vec2(r1.origin.x + 300,r1.origin.y/2 + r1.size.height -300);
child2->setPosition(v2);
auto action = 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 = "Images/grossini.png");
Vec2(r1.origin.x +300,r1.origin.y/2 +r1.size.height -300);
child2->setPosition(v2);
addChild(child2,111);
auto pmove = MoveBy::create(2,175); font-family:新宋体; font-size:9.5pt">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 = auto pmove2 = auto pSequenceMove = Sequence::createWithTwoActions(pmove1,pmove2);
auto pRepeatMove = RepeatForever::create(pSequenceMove);
pRepeatMove->setTag(111);
auto pScale1 = ScaleBy::create(2,1.5f);
auto pScale2 = 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 = Rect r = 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);
}
六、一段时间后执行一次某个动作
auto child = "Images/grossini.png");
addChild(child,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(}