Cocos2d-x怎样控制动作速度
基本动作和组合动作实现了针对精灵的各种运动和动画效果的改变。但这种改变速度匀速的、线性的。通过ActionEase及其的派生类和Speed 类我们能够使精灵以非匀速或非线性速度运动,这样看起了效果更加逼真。
ActionEase的类图例如以下图所看到的。
以下我们通过一个实例介绍一下这些动作中速度的控制的使用,这个实比例如以下图所看到的,上图是一个操作菜单场景,选择菜单能够进入到下图动作场景,在下图动作场景中点击Gobutton能够运行我们选择的动作效果,点击Backbutton能够返回到菜单场景。
以下我们再看看详细的程序代码,首先看一下看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))) 随机设置变换速度。
京东:http://item.jd.com/11584534.html
当当:http://product.dangdang.com/23606265.html
互动出版网:http://product.china-pub.com/3770734
《Cocos2d-x实战 C++卷》源代码及样章下载地址:
源代码下载地址:http://51work6.com/forum.php?mod=viewthread&tid=1155&extra=page%3D1
样章下载地址:http://51work6.com/forum.php?mod=viewthread&tid=1157&extra=page%3D1