cocos2dx 幾個精靈依照順序播放動畫解決方法
阿新 • • 發佈:2017-05-31
-m break callback empty ref 返回 ins 添加 track
這裏使用了push_action函數,作用是播放動作或者將操作存入容器:
函數的作用是依據傳入的兩個tag播放動作,然後調用next_action:
假設容器裏沒有數據則說明接下來沒有動作能夠播放了,則把isRunAction賦為false,下次就能夠直接播放動作。
非常easy,就是一個動作。當然我們能夠依據須要添加。(註意返回參數是Sequence,所以想播放其它動畫就改函數吧)
我先描寫敘述一下這個問題:
拿之前做的卡牌遊戲來說。假設一方場上有3張牌,那麽肯定要以一種順序來播放攻擊動畫。我是以從左到右的方式。
我的解決方案是向每張牌都傳遞一個延時參數,然後在runAction的時候使用DelyTime,可是這樣的方法太麻煩。
如今說說更好的方法吧:
基本思路是vector與callfunc相結合。
一:
先在類裏定義數據和函數
std::vector<std::vector<int>> v_action;//儲存精靈TAG和動畫TAG的容器 void push_action(int sprite_tag,int action_tag);//加入動作序列 void run_action(int sprite_tag,int action_tag);//播放動作 void next_action();//下一個動作 Sequence* run(int action_tag);//依據TAG返回動作 bool isRunAction;//是否正在播放動作
二:
在init初始化參數
//還沒有播放動作 isRunAction=false; Size visibleSize = Director::getInstance()->getVisibleSize(); Vec2 origin = Director::getInstance()->getVisibleOrigin(); //演員一 auto actor1 = Sprite::create("CloseNormal.png"); actor1->setTag(11); actor1->setPosition(250,visibleSize.height/2); this->addChild(actor1,2); //演員二 auto actor2 = Sprite::create("CloseNormal.png"); actor2->setTag(22); actor2->setPosition(300,visibleSize.height/2); this->addChild(actor2,2); //演員一跳躍 auto play1 = MenuItemImage::create( "CloseNormal.png", "CloseSelected.png", CC_CALLBACK_1(HelloWorld::menuCallback, this)); play1->setTag(1); play1->setPosition(250,visibleSize.height/5); //演員二跳躍 auto play2 = MenuItemImage::create( "CloseNormal.png", "CloseSelected.png", CC_CALLBACK_1(HelloWorld::menuCallback, this)); play2->setTag(2); play2->setPosition(300,visibleSize.height/5); auto closeItem = MenuItemImage::create( "CloseNormal.png", "CloseSelected.png", CC_CALLBACK_1(HelloWorld::menuCloseCallback, this)); closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 , origin.y + closeItem->getContentSize().height/2)); // create menu, it‘s an autorelease object auto menu = Menu::create(play1,play2,closeItem, NULL); menu->setPosition(Vec2::ZERO); this->addChild(menu, 1);
void HelloWorld::menuCallback(Ref* pSender) { auto menuItem = (MenuItemImage*)pSender; Sprite* actor; switch (menuItem->getTag()) { case 1: push_action(11,1); break; case 2: push_action(22,1); break; default: break; } }
這裏使用了push_action函數,作用是播放動作或者將操作存入容器:
void HelloWorld::push_action(int sprite_tag,int action_tag) { if(isRunAction==false)//假設沒有在播放動作,那麽直接播放此動作 { isRunAction=true; run_action(sprite_tag,action_tag); } else//假設正在播放,那麽將此動作存入容器 { std::vector<int> v_sprite; v_sprite.push_back(sprite_tag); v_sprite.push_back(action_tag); v_action.push_back(v_sprite); } }
凝視已經比較具體了~
我們先看看run_action函數裏面有什麽吧:void HelloWorld::run_action(int sprite_tag,int action_tag) { auto actor = (Sprite*)getChildByTag(sprite_tag); auto squence = Sequence::create(run(action_tag), CallFunc::create(this,callfunc_selector(HelloWorld::next_action)), NULL); actor->runAction(squence); }
函數的作用是依據傳入的兩個tag播放動作,然後調用next_action:
void HelloWorld::next_action() { if(v_action.empty()) { isRunAction=false; } else { std::vector<int > a; a=v_action.at(0); int sprite_tag=a.at(0); int action_tag=a.at(1); std::vector<std::vector<int>>::iterator it = v_action.begin(); v_action.erase(it); run_action(sprite_tag,action_tag); } }
假設容器裏沒有數據則說明接下來沒有動作能夠播放了,則把isRunAction賦為false,下次就能夠直接播放動作。
假設容器裏有數據。我們先把這項數據取出然後刪除它。然後再調用run_action。
最後我們看看run裏面有什麽吧:
Sequence* HelloWorld::run(int action_tag) { switch (action_tag) { case 1: return Sequence::create(MoveBy::create(0.2,Vec2(0,100)), MoveBy::create(0.2,Vec2(0,-100)), NULL); default: break; } }
非常easy,就是一個動作。當然我們能夠依據須要添加。(註意返回參數是Sequence,所以想播放其它動畫就改函數吧)
如今看看效果:
完畢!
cocos2dx 幾個精靈依照順序播放動畫解決方法