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(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));
}