Cocos2d-x如何控制動作速度,cocos2d-x控制動作
基本動作和組合動作實現了針對精靈的各種運動和動畫效果的改變。但這樣的改變速度勻速的、線性。通過ActionEase及其的衍生類別和Speed 類我們可以使精靈以非勻速或非線性速度運動,這樣看起了效果更加逼真。
ActionEase的類圖如所示。
下面我們通過一個執行個體介紹一下這些動作中速度的控制的使用,這個執行個體如所示,是一個操作菜單情境,選擇菜單可以進入到動作情境,在動作情境中點擊Go按鈕可以執行我們選擇的動作效果,點擊Back按鈕可以返回到菜單情境。
下面我們再看看具體的程式碼,首先看一下看HelloWorldScene.h檔案,它的代碼如下:
#ifndef __HELLOWORLD_SCENE_H__#define __HELLOWORLD_SCENE_H__ #include "cocos2d.h"#include "MyActionScene.h" typedef enum ①{ kEaseIn = 1 ,kEaseOut ,kEaseInOut ,kEaseSineIn ,kEaseSineOut ,kEaseSineInOut ,kEaseExponentialIn ,kEaseExponentialOut ,kEaseExponentialInOut ,kSpeed } ActionTypes; ② class HelloWorld : public cocos2d::Layer{public: static cocos2d::Scene* createScene(); virtual bool init(); void OnClickMenu(cocos2d::Ref* pSender); CREATE_FUNC(HelloWorld);}; #endif // __HELLOWORLD_SCENE_H__
上述代碼第①~②是定義個枚舉類型ActionTypes,枚舉類型ActionTypes中定義了10個常量,這10個常量對應10個功能表項目。
HelloWorldScene的實現代碼HelloWorldScene.ccp檔案,它的主要代碼如下:
bool HelloWorld::init(){ if( !Layer::init() ) { returnfalse; } SizevisibleSize = Director::getInstance()->getVisibleSize(); Pointorigin = Director::getInstance()->getVisibleOrigin(); autobg = Sprite::create("background.png"); bg->setPosition(Point(visibleSize.width/2,visibleSize.height /2)); this->addChild(bg); autopItmLabel1 = Label::createWithBMFont("fonts/fnt2.fnt","EaseIn"); autopItmMenu1 = MenuItemLabel::create(pItmLabel1, CC_CALLBACK_1(HelloWorld::OnClickMenu, this)); pItmMenu1->setTag(kEaseIn); autopItmLabel2 = Label::createWithBMFont("fonts/fnt2.fnt","EaseOut"); autopItmMenu2 = MenuItemLabel::create(pItmLabel2, CC_CALLBACK_1(HelloWorld::OnClickMenu,this)); pItmMenu2->setTag(kEaseOut); autopItmLabel3 = Label::createWithBMFont("fonts/fnt2.fnt","EaseInOut"); autopItmMenu3 = MenuItemLabel::create(pItmLabel3, CC_CALLBACK_1(HelloWorld::OnClickMenu,this)); pItmMenu3->setTag(kEaseInOut); autopItmLabel4 = Label::createWithBMFont("fonts/fnt2.fnt","EaseSineIn"); autopItmMenu4 = MenuItemLabel::create(pItmLabel4, CC_CALLBACK_1(HelloWorld::OnClickMenu,this)); pItmMenu4->setTag(kEaseSineIn); autopItmLabel5 = Label::createWithBMFont("fonts/fnt2.fnt", "EaseSineOut"); autopItmMenu5 = MenuItemLabel::create(pItmLabel5, CC_CALLBACK_1(HelloWorld::OnClickMenu,this)); pItmMenu5->setTag(kEaseSineOut); autopItmLabel6 = Label::createWithBMFont("fonts/fnt2.fnt","EaseSineInOut"); autopItmMenu6 = MenuItemSprite::create(pItmLabel6, CC_CALLBACK_1(HelloWorld::OnClickMenu,this)); pItmMenu6->setTag(kEaseSineInOut); autopItmLabel7 = Label::createWithBMFont("fonts/fnt2.fnt","EaseExponentialIn"); autopItmMenu7 = MenuItemSprite::create(pItmLabel7, CC_CALLBACK_1(HelloWorld::OnClickMenu,this)); pItmMenu7->setTag(kEaseExponentialIn); autopItmLabel8 = Label::createWithBMFont("fonts/fnt2.fnt","EaseExponentialOut"); autopItmMenu8 = MenuItemLabel::create(pItmLabel8, CC_CALLBACK_1(HelloWorld::OnClickMenu,this)); pItmMenu8->setTag(kEaseExponentialOut); autopItmLabel9 = Label::createWithBMFont("fonts/fnt2.fnt","EaseExponentialInOut"); autopItmMenu9 = MenuItemLabel::create(pItmLabel9, CC_CALLBACK_1(HelloWorld::OnClickMenu,this)); pItmMenu9->setTag(kEaseExponentialInOut); autopItmLabel10 = Label::createWithBMFont("fonts/fnt2.fnt","Speed"); autopItmMenu10 = MenuItemLabel::create(pItmLabel10, CC_CALLBACK_1(HelloWorld::OnClickMenu,this)); pItmMenu10->setTag(kSpeed); automn = Menu::create(pItmMenu1,pItmMenu2,pItmMenu3,pItmMenu4,pItmMenu5, pItmMenu6,pItmMenu7,pItmMenu8,pItmMenu9,pItmMenu10,NULL); mn->alignItemsInColumns(2,2, 2, 2, 2, NULL); this->addChild(mn); returntrue;} void HelloWorld::OnClickMenu(Ref* pSender){ MenuItem*nmitem = (MenuItem*)pSender; auto sc = Scene::create(); auto layer = MyAction::create(); layer->setTag(nmitem->getTag()); sc->addChild(layer); autoreScene = TransitionSlideInR::create(1.0f, sc); Director::getInstance()->replaceScene(reScene);}
在上訴代碼大家比較熟悉了,我們這裡就不再介紹了。下面我們再看看下一個情境MyActionScene,它的MyActionScene.ccp,它的主要代碼如下:
void MyAction::goMenu(Ref* pSender){ log("Tag = %i",this->getTag()); FiniteTimeAction * ac1 = (FiniteTimeAction *)MoveBy::create(2,Point(200, 0)); FiniteTimeAction * ac2 = ((FiniteTimeAction *)ac1)->reverse(); ActionInterval * ac = Sequence::create(ac1, ac2, NULL); switch (this->getTag()) { case kEaseIn: sprite->runAction(EaseIn::create(ac, 3)); ① break; case kEaseOut: sprite->runAction(EaseOut::create(ac, 3)); ② break; case kEaseInOut: sprite->runAction(EaseInOut::create(ac,3)); ③ break; case kEaseSineIn: sprite->runAction(EaseSineIn::create(ac)); ④ break; case kEaseSineOut: sprite->runAction(EaseSineOut::create(ac)); ⑤ break; case kEaseSineInOut: sprite->runAction(EaseSineInOut::create(ac)); ⑥ break; case kEaseExponentialIn: sprite->runAction(EaseExponentialIn::create(ac)); ⑦ break; case kEaseExponentialOut: sprite->runAction(EaseExponentialOut::create(ac)); ⑧ break; case kEaseExponentialInOut: sprite->runAction(EaseExponentialInOut::create(ac)); ⑨ break; case kSpeed: sprite->runAction(Speed::create(ac, (CCRANDOM_0_1() * 5))); ⑩ break; }}
第①行代碼sprite->runAction(EaseIn::create(ac, 3))是以3倍速度由慢至快。第②代碼sprite->runAction(EaseOut::create(ac, 3))是以3倍速度由快至慢。第③代碼sprite->runAction(EaseInOut::create(ac, 3))是以3倍速度由慢至快再由快至慢。
第④代碼sprite->runAction(EaseSineIn::create(ac))是採用正弦變換速度由慢至快。第⑤代碼sprite->runAction(EaseSineOut::create(ac))是採用正弦變換速度由快至慢。第⑥代碼sprite->runAction(EaseOut::create(ac, 3)) 是採用正弦變換速度由慢至快再由快至慢。
第⑦代碼sprite->runAction(EaseExponentialIn::create(ac))採用指數變換速度由慢至快。第⑧代碼sprite->runAction(EaseExponentialOut::create(ac))採用指數變換速度由快至慢。第⑨代碼sprite->runAction(EaseExponentialInOut::create(ac)) 採用指數變換速度由慢至快再由快至慢。
第⑩代碼sprite->runAction(Speed::create(ac, (CCRANDOM_0_1() * 5))) 隨機設定變換速度。
更多內容請關注Cocos2d-x系列圖書《Cocos2d-x實戰(卷Ⅰ):C++開發》本書交流討論網站:http://www.cocoagame.net歡迎加入cocos2d-x技術討論群:257760386、327403678
cocos2d-x Sprite Action 問題
#define THETAG 123/*這數字隨你定*/
初始化動作:
CCAction*pAction=你要執行的動作;
pAction->setTag(THETAG);
pSprite->runAction(pAction); //你原本執行的動作
加速:
pSprite->stopActionByTag(THETAG);
pAction=CCSpeed::actionWithAction(
你要執行的動作/*注意時間這裡要設定為20秒,因為加速實際就是十秒執行20秒的動作*/,
2/*如果要減速就是0.7*/);
pAction->setTag(THETAG);
pSprite->runAction(CCSequence::actions(
pAction,
CCCallFunc::actionWithTarget(pSprite,callfunc_selector(回呼函數)),
NULL
));
下面是回呼函數內部://這函數為執行動作的精靈的成員函數
stopActionByTag(THETAG);
CCAction*pAction=你要執行的動作;
pAction->setTag(THETAG);
runAction(pAction);
cocos2d-x,怎實現精靈在一個動作結束前不響應其他觸摸事件
這個問題很普遍,就是你點擊一次,讓它跳一下。等落下來了,再點一次,再跳一次。動畫過程中點擊不會跳躍。
一般在遊戲開發中,我們都習慣用一個bool en變數來控制,你先點擊事件中,也就是這個精靈runAction();的時候en設為false,並且跳躍動畫推薦有jumpBy,在其中添加一個回調,專門用來當動畫結束是將en設為true。
建議多看看damo。謝謝~祝你成長。