1、头文件
//.h #include "cocos2d.h" #include "ui/CocosGUI.h" #include "VisibleRect.h" USING_NS_CC; using namespace ui; class ActionManagerDemo : public Scene { public: CREATE_FUNC(ActionManagerDemo); virtual bool init(); }; class BaseTest : public Layer { public: CREATE_FUNC(BaseTest); virtual bool init(); virtual std::string title() const;//主标题 virtual std::string subtitle() const;//副标题 virtual void onExit() override; virtual void restartCallback(Ref* sender);//重新执行当前test virtual void nextCallback(Ref* sender);//下一个test virtual void backCallback(Ref* sender);//上一个test void menuCloseCallback(cocos2d::Ref* pSender);//关闭菜单回调函数 protected: TextureAtlas* _atlas; std::string _title; }; class CrashTest : public BaseTest { public: CREATE_FUNC(CrashTest); CrashTest(); virtual bool init(); virtual std::string subtitle() const override; virtual void onEnter() override; void removeThis(); }; // class LogicTest : public BaseTest { public: CREATE_FUNC(LogicTest); virtual std::string subtitle() const override; virtual void onEnter() override; void bugMe(Node* node); }; class PauseTest : public BaseTest { public: CREATE_FUNC(PauseTest); virtual std::string subtitle() const override; virtual void onEnter() override; void unpause(float dt); }; class StopActionTest : public BaseTest { public: CREATE_FUNC(StopActionTest); virtual std::string subtitle() const override; virtual void onEnter() override; void stopAction(); }; class StopAllActionsTest : public BaseTest { public: CREATE_FUNC(StopAllActionsTest); virtual std::string subtitle() const override; virtual void onEnter() override; void stopAction(float time); }; class ResumeTest : public BaseTest { public: CREATE_FUNC(ResumeTest); virtual std::string subtitle() const override; virtual void onEnter() override; void resumeGrossini(float time); };
2、cpp文件
#include "ActionManagerDemo.h" #define CL(__className__) [](){ return __className__::create();} static int sceneIdx = -1; enum { kTagNode,kTagGrossini,kTagSequence }; static std::function<Layer*()> createFunctions[] = { CL(CrashTest),CL(LogicTest),CL(PauseTest),CL(StopActionTest),CL(StopAllActionsTest),CL(ResumeTest) }; #define MAX_LAYER (sizeof(createFunctions) / sizeof(createFunctions[0])) static Layer* nextAction() { sceneIdx++; sceneIdx = sceneIdx % MAX_LAYER; auto layer = (createFunctions[sceneIdx])(); return layer; } static Layer* backAction() { sceneIdx--; int total = MAX_LAYER; if( sceneIdx < 0 ) sceneIdx += total; auto layer = (createFunctions[sceneIdx])(); return layer; } static Layer* restartAction() { auto layer = (createFunctions[sceneIdx])(); return layer; } //基类Layer bool BaseTest::init() { bool bRet = false; do{ CC_BREAK_IF(!Layer::init()); Size visibleSize = Director::getInstance()->getVisibleSize(); Vec2 origin = Director::getInstance()->getVisibleOrigin(); ///////////////////////////// // 2. add a menu item with "X" image,which is clicked to quit the program // you may modify it. // add a "close" icon to exit the progress. it's an autorelease object auto closeItem = MenuItemImage::create( "CloseNormal.png","CloseSelected.png",CC_CALLBACK_1(BaseTest::menuCloseCallback,this)); closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2,origin.y + visibleSize.height - closeItem->getContentSize().height/2)); // create menu,it's an autorelease object auto menu1 = Menu::create(closeItem,NULL); menu1->setPosition(Vec2::ZERO); this->addChild(menu1,1); std::string str = title(); const char * pTitle = str.c_str(); TTFConfig ttfConfig("fonts/tahoma.ttf",35); auto label = Label::createWithTTF(ttfConfig,pTitle); addChild(label,9999); label->setPosition( Vec2(VisibleRect::center().x,VisibleRect::top().y - 30) ); std::string strSubtitle = subtitle(); if( ! strSubtitle.empty() ) { ttfConfig.fontFilePath = "fonts/tahoma.ttf"; ttfConfig.fontSize = 30; auto l = Label::createWithTTF(ttfConfig,strSubtitle.c_str()); addChild(l,9999); l->setPosition( Vec2(VisibleRect::center().x,VisibleRect::top().y - 100) ); } auto item1 = MenuItemFont::create("backCallback",CC_CALLBACK_1(BaseTest::backCallback,this) ); auto item2 = MenuItemFont::create("restartCallback",CC_CALLBACK_1(BaseTest::restartCallback,this) ); auto item3 = MenuItemFont::create("nextCallback",CC_CALLBACK_1(BaseTest::nextCallback,this) ); auto menu = Menu::create(item1,item2,item3,NULL); menu->setPosition(Vec2::ZERO); item1->setPosition(Vec2(VisibleRect::center().x - item2->getContentSize().width*2,VisibleRect::bottom().y+item2->getContentSize().height/2)); item2->setPosition(Vec2(VisibleRect::center().x,VisibleRect::bottom().y+item2->getContentSize().height/2)); item3->setPosition(Vec2(VisibleRect::center().x + item2->getContentSize().width*2,VisibleRect::bottom().y+item2->getContentSize().height/2)); addChild(menu,9999); bRet = true; }while(0); return bRet; } void BaseTest::menuCloseCallback(Ref* pSender) { #if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert"); return; #endif Director::getInstance()->end(); #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) exit(0); #endif } //重新执行当前test void BaseTest::restartCallback(cocos2d::Ref *sender) { auto s = new (std::nothrow) ActionManagerDemo(); s->addChild(restartAction()); Director::getInstance()->replaceScene(s); s->release(); } //下一个test void BaseTest::nextCallback(cocos2d::Ref *sender) { auto s = new (std::nothrow) ActionManagerDemo(); s->addChild(nextAction()); Director::getInstance()->replaceScene(s); s->release(); } //上一个test void BaseTest::backCallback(cocos2d::Ref *sender) { auto s = new (std::nothrow) ActionManagerDemo(); s->addChild(backAction()); Director::getInstance()->replaceScene(s); s->release(); } //onExit函数 void BaseTest::onExit() { Layer::onExit(); } std::string BaseTest::title() const { return "NewAudioEngineDemo Test"; } std::string BaseTest::subtitle() const { return ""; } bool ActionManagerDemo::init() { bool bRet = false; do{ CC_BREAK_IF(!Scene::init()); //初始化sceneIdx sceneIdx = -1; //执行nextAction,执行第一个test auto layer = nextAction(); //加入NewAudioEngineDemo场景 addChild(layer); //切换场景 Director::getInstance()->replaceScene(this); bRet = true; }while(0); return bRet; } CrashTest::CrashTest() { log("--------构造函数--------"); } void CrashTest::onEnter() { log("-------onEnter函数---------"); BaseTest::onEnter(); //创建对象 auto child = Sprite::create("grossini.png"); child->setPosition(VisibleRect::center()); addChild(child,1); //精灵执行动作 child->runAction(RotateBy::create(1.5f,90)); child->runAction(Sequence::create(DelayTime::create(1.5f),FadeOut::create(1.1f),NULL)); //当前Layer对象执行动作 runAction(Sequence::create(DelayTime::create(1.5f),CallFunc::create(CC_CALLBACK_0(CrashTest::removeThis,this)),NULL)); } bool CrashTest::init() { bool bRet = false; do{ CC_BREAK_IF(!BaseTest::init()); log("------init函数--------"); bRet = true; }while(0); return bRet; } void CrashTest::removeThis() { //首先调用父对象,即Scene对象,删除当前Layer对象,然后执行下一test _parent->removeChild(this,true); nextCallback(this); } std::string CrashTest::subtitle() const { return "Crash Test"; } void LogicTest::onEnter() { BaseTest::onEnter(); auto grossini = Sprite::create("grossini.png"); addChild(grossini,2); grossini->setPosition(VisibleRect::center()); grossini->runAction(Sequence::create(MoveBy::create(1,Vec2(150,0)),CallFuncN::create(CC_CALLBACK_1(LogicTest::bugMe,NULL)); } void LogicTest::bugMe(cocos2d::Node *node) { node->stopAllActions(); node->runAction(ScaleTo::create(2,2)); } std::string LogicTest::subtitle() const { return "Logic Test"; } void PauseTest::onEnter() { BaseTest::onEnter(); auto l = Label::createWithTTF("After 3 seconds grossini should move","fonts/arial.ttf",16.0f); addChild(l); l->setPosition(VisibleRect::center().x,VisibleRect::top().y-75); //创建对象 auto grossini = Sprite::create("grossini.png"); addChild(grossini,kTagGrossini); grossini->setPosition(VisibleRect::center()); //创建动作 auto action = MoveBy::create(1,0)); auto director = Director::getInstance(); //参数依次为动作,动作执行者,是否暂停 director->getActionManager()->addAction(action,grossini,true); //3秒后执行unpause函数 schedule(CC_SCHEDULE_SELECTOR(PauseTest::unpause),3); } void PauseTest::unpause(float dt) { //停止帧跟新 unschedule(CC_SCHEDULE_SELECTOR(PauseTest::unpause)); auto node = getChildByTag(kTagGrossini); auto director = Director::getInstance(); //因为加入动作Manager时,是设置pause的,所以恢复动作 director->getActionManager()->resuMetarget(node); } std::string PauseTest::subtitle() const { return "Pause Test"; } void StopActionTest::onEnter() { BaseTest::onEnter(); auto l = Label::createWithTTF("Should not crash",VisibleRect::top().y - 75); //创建动作 auto pMove = MoveBy::create(2,Vec2(200,0)); auto pCallback = CallFunc::create(CC_CALLBACK_0(StopActionTest::stopAction,this)); auto pSequence = Sequence::create(pMove,pCallback,nullptr); pSequence->setTag(kTagSequence); //创建对象 auto pChild = Sprite::create("grossini.png"); pChild->setPosition(VisibleRect::center()); addChild(pChild,1,kTagGrossini); //对象执行动作,在Action动作序列中执行stopAction函数 pChild->runAction(pSequence); } void StopActionTest::stopAction() { //暂停对象的动作 auto sprite = getChildByTag(kTagGrossini); sprite->stopActionByTag(kTagSequence); } std::string StopActionTest::subtitle() const { return "Stop Action Test"; } void StopAllActionsTest::onEnter() { BaseTest::onEnter(); auto l = Label::createWithTTF("Should stop scale & move after 4 seconds but keep rotate",25.0f); addChild(l); l->setPosition( Vec2(VisibleRect::center().x,VisibleRect::top().y - 75) ); //创建动作 auto pMove1 = MoveBy::create(2,0)); auto pMove2 = MoveBy::create(2,Vec2(-200,0)); auto pSequenceMove = Sequence::createWithTwoActions(pMove1,pMove2); auto pRepeatMove = RepeatForever::create(pSequenceMove); pRepeatMove->setTag(kTagSequence); 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(kTagSequence); auto pRotate = RotateBy::create(2,360); auto pRepeatRotate = RepeatForever::create(pRotate); //创建精灵 auto pChild = Sprite::create("grossini.png"); pChild->setPosition(VisibleRect::center()); addChild(pChild,kTagGrossini); //执行动作 pChild->runAction(pRepeatMove); pChild->runAction(pRepeatScale); pChild->runAction(pRepeatRotate); //每4秒更新一帧 scheduleOnce((SEL_SCHEDULE)&StopAllActionsTest::stopAction,4); } void StopAllActionsTest::stopAction(float time) { //暂停对象的所有动作 auto sprite = getChildByTag(kTagGrossini); sprite->stopAllActionsByTag(kTagSequence); } std::string StopAllActionsTest::subtitle() const { return "Stop All Action Test"; } void ResumeTest::onEnter() { BaseTest::onEnter(); auto l = Label::createWithTTF("Grossini only rotate/scale in 3 seconds",VisibleRect::top().y - 75); //创建精灵 auto pChild = Sprite::create("grossini.png"); pChild->setPosition(VisibleRect::center()); addChild(pChild,kTagGrossini); //精灵执行动作 pChild->runAction(ScaleBy::create(2,2)); //首先暂停对象动作 auto director = Director::getInstance(); director->getActionManager()->pauseTarget(pChild); pChild->runAction(RotateBy::create(2,90)); //每3秒更新一帧 schedule(CC_SCHEDULE_SELECTOR(ResumeTest::resumeGrossini),3.0f); } void ResumeTest::resumeGrossini(float time) { //先暂停帧更新 unschedule(CC_SCHEDULE_SELECTOR(ResumeTest::resumeGrossini)); //获取对象 auto pGrossini = getChildByTag(kTagGrossini); auto director = Director::getInstance(); //开启对象的动作 director->getActionManager()->resuMetarget(pGrossini); } std::string ResumeTest::subtitle() const { return "Resume Test"; }
3、学习重点
1、grossini->runAction(Sequence::create(MoveBy::create(1,Vec2(150,0)),CallFuncN::create(CC_CALLBACK_1(LogicTest::bugMe,this)),NULL));
2、director->getActionManager()->addAction(action,true); schedule(CC_SCHEDULE_SELECTOR(PauseTest::unpause),3);
3、unschedule(CC_SCHEDULE_SELECTOR(PauseTest::unpause)); director->getActionManager()->resuMetarget(node);
4、auto pCallback = CallFunc::create(CC_CALLBACK_0(StopActionTest::stopAction,this));
5、sprite->stopAllActionsByTag(kTagSequence);
5、sprite->stopAllActionsByTag(kTagSequence);
一个tag值可以设置多个对象,并且,getTag时返回所有对象。