【麦可网】Cocos2d-X跨平台游戏开发---学习笔记
第十七课:Cocos2D-X动作行为1-5
=======================================================================================================================================================================
课程目标:
-Cocos2D-X动画系统
课程重点:
-Cocos2D-X动作类型
-Cocos2D-X动作管理器
考核目标:
-Cocos2D-X如何执行动画
-Cocos2D-X动作类型
-Cocos2D-X动作管理器
=======================================================================================================================================================================
动作执行
CCAction*runAction(CCAction*action)
一、动作类型
1.瞬时动作
CCactionstant - CCPlace 移动到某个位置 - CCHide/CCShow <span style="white-space:pre"> </span>显示或者隐藏 - CCToggleVisibility <span style="white-space:pre"> </span>反转显示、隐藏(隐藏时运行后显示,显示时运行后隐藏) - CCFlipX/CCFlipY 绕X轴或者Y轴翻转
------------------------------------------------------------------------ CCPlace *place = CCPlace::create(ccp(size.width/2,size.height/2)); pLabel->runAction(place); ------------------CCHide/CCShow------------------ CCHide *hide = CCHide::create(); pLabel->runAction(hide); CCShow *show = CCShow::create(); pLabel->runAction(show); ------------------CCToggleVisibility------------------ CCToggleVisibility *showhide1 = CCToggleVisibility::create(); pLabel->runAction(showhide1); CCToggleVisibility *showhide2 = CCToggleVisibility::create(); pLabel->runAction(showhide2); ------------------CCFlipX/CCFlipY------------------ CCFlipX *flipX = CCFlipX::create(true); pLabel->runAction(flipX); CCFlipY *flipY = CCFlipY::create(true); pLabel->runAction(flipY);
2.延时动作
CCActionInterval - CCMoveTo/CCMoveBy 移动到(参数)位置/移动到(本身坐标+参数)的位置 - CCJumpTo/CCJumpBy 跳到某个地址(to:目的地址,by相对地址) - CCBezierTo/CCBezierBy 按着贝塞尔曲线移动 - CCScaleTo/CCScaleBy to:缩放到多少;by:缩放多少倍 - CCRotateTo/CCRotateBy - CCBlink 闪烁 - CCTintTo/CCTintBy 色调变化 注:CCTinitTo不能使用reverse方法。 - CCFadeTo 变暗到 - CCFadeIn 淡出 - CCFadeOut 渐隐 ------------------CCMoveTo/CCMoveBy------------------ CCMoveTo *moveto = CCMoveTo::create(3.0f,ccp(size.width/2,size.height/2+50)); pLabel->runAction(moveto); CCMoveBy *moveby = CCMoveBy::create(3.0f,ccp(-50,-50)); pLabel->runAction(moveby); ------------------CCJumpTo/CCJumpBy------------------ CCJumpTo *jumpto = CCJumpTo::create(3.0f,ccp(size.width,size.height),50,3); pLabel->runAction(jumpto); CCJumpBy *jumpby = CCJumpBy::create(3.0f,ccp(50,50),10,5); pLabel->runAction(jumpby); ------------------CCBezierTo/CCBezierBy------------------ ccBezierConfig beziercofig; beziercofig.controlPoint_1 = ccp(200,300); beziercofig.controlPoint_2 = ccp( 100,100); beziercofig.endPosition = ccp(100,100); CCActionInterval *bezierby1 = CCBezierBy::create(3.0f,beziercofig); <span style="white-space:pre"> </span>//原轨迹返回 <span style="white-space:pre"> </span>CCActionInterval *bezierby2 = bezierby1->reverse();
<span style="white-space:pre"> </span>CCAction *actionRe = CCRepeatForever::create(CCSequence::create( bezierby1,bezierby2,NULL)); pLabel->runAction(actionRe); ------------------CCScaleTo/CCScaleBy------------------ CCScaleTo *scaleto = CCScaleTo::create(3.0f,2.0f,2.0f); pLabel->runAction(scaleto); CCScaleBy *scaleby = CCScaleBy::create(3.0f,2.0f); pLabel->runAction(scaleby); ------------------CCRotateTo/CCRotateBy------------------ CCRotateTo *rotateto = CCRotateTo::create(3.0f,45.0f,45.0f); pLabel->runAction(rotateto); CCRotateBy *rotateby = CCRotateBy::create(3.0f,-45.0f,-45.0f); pLabel->runAction(rotateby); ------------------CCBlink------------------ CCBlink *blink = CCBlink::create(3.0f,5); pLabel->runAction(blink); ------------------CCTintTo/CCTintBy------------------ CCTintTo *tintto = CCTintTo::create(3.0f,255,0); pLabel->runAction(tintto); CCTintBy *tintby = CCTintBy::create(3.0f,0); tintby->reverse(); pLabel->runAction(tintby); ------------------CCFadeTo------------------ CCFadeTo *fadeto = CCFadeTo::create(3.0f,100); pLabel->runAction(fadeto); CCFadeIn *fadein = CCFadeIn::create(3.0f); pLabel->runAction(fadein); ------------------CCFadeIn------------------ CCFadeIn *fadein = CCFadeIn::create(3.0f); pLabel->runAction(fadein); ------------------CCFadeOut------------------ CCFadeOut *fadeout = CCFadeOut::create(3.0f); pLabel->runAction(fadeout);
3.组合动作
- 序列:CCSequence - 同步:CCSpawn - 重复有限次:CCRepeat - 反动作:reverse - 无限重复:CCRepeatForever - 帧动画:CCAnimate ------------------CCSequence------------------ CCTintTo *tintto = CCTintTo::create(3.0f,0); CCFadeOut *fadeout = CCFadeOut::create(3.0f); CCFiniteTimeAction *sequence = CCSequence::create(tintto,fadeout,NULL); pLabel->runAction(sequence); ------------------CCSpawn------------------ CCTintTo *tintto = CCTintTo::create(3.0f,0); CCFadeOut *fadeout = CCFadeOut::create(3.0f); CCFiniteTimeAction *spawn = CCSpawn::create(tintto,NULL); pLabel->runAction(spawn); ------------------CCRepeat------------------ CCFadeOut *fadeout = CCFadeOut::create(3.0f); CCRepeat *repeat = CCRepeat::create(fadeout,5.0f); pLabel->runAction(repeat); ------------------reverse/CCRepeatForever------------------ ccBezierConfig beziercofig; beziercofig.controlPoint_1 = ccp(200,NULL)); pLabel->runAction(actionRe); ------------------CCAnimate------------------ CCSize size = CCDirector::sharedDirector()->getWinSize(); CCSprite *google = CCSprite::create("gg01.png"); google->setPosition(ccp(size.width/2,size.height/2)); this->addChild(google,1); int framCount = 5; char str[50] = {0}; CCArray *frameArray = CCArray::create(); for (int i=1; i<=framCount; i++) { sprintf(str,"gg0%d.png",i); CCSpriteFrame *frame = CCSpriteFrame::create(str,CCRectMake(0,320,533)); frameArray->addObject(frame); } CCAnimation *animation = CCAnimation::createWithSpriteFrames(frameArray,0.2f); <span style="white-space:pre"> </span>frameArray->release(); CCAnimate *animate = CCAnimate::create(animation); google->runAction(CCRepeatForever::create(animate));
4.速度变换
- CCEaseIn <span style="white-space:pre"> </span>又慢到快(速度线性变换) - CCEaSEOut <span style="white-space:pre"> </span>又快到慢 - CCEaseSineInOut <span style="white-space:pre"> </span>由慢至快再由快至慢 - CCeaseSineIn <span style="white-space:pre"> </span>由慢至快(速度正弦变换) - CCEaseSineOut <span style="white-space:pre"> </span>由快至慢(速度正弦变换) - CCEaseSineInOut<span style="white-space:pre"> </span>由慢至快再由快至慢 - CCEaseExponentialIn <span style="white-space:pre"> </span>由慢至极快(速度指数级变换) - CCEaseExponentialOut<span style="white-space:pre"> </span>由快至极慢(速度指数级变换) - CCEaseExponentialInOut 由慢至极快再由快至极慢 - CCSpeed 人工设定速度,通过setSpeed不断调整 参考代码:tests->ActionsEaseTest -------------------CCEaseIn/CCEaSEOut ------------------- #define CCCA(x) (x->copy()->autorelease()) void SpriteEase::onEnter() { EaseSpriteDemo::onEnter(); CCActionInterval* move = CCMoveBy::create(3,ccp(VisibleRect::right().x-130,0)); CCActionInterval* move_back = move->reverse(); CCActionInterval* move_ease_in = CCEaseIn::create((CCActionInterval*)(move->copy()->autorelease()),2.5f); CCActionInterval* move_ease_in_back = move_ease_in->reverse(); CCActionInterval* move_ease_out = CCEaSEOut::create((CCActionInterval*)(move->copy()->autorelease()),2.5f); CCActionInterval* move_ease_out_back = move_ease_out->reverse(); CCDelayTime *delay = CCDelayTime::create(0.25f); CCSequence* seq1 = CCSequence::create(move,delay,move_back,CCCA(delay),NULL); CCSequence* seq2 = CCSequence::create(move_ease_in,move_ease_in_back,NULL); CCSequence* seq3 = CCSequence::create(move_ease_out,move_ease_out_back,NULL); CCAction *a2 = m_grossini->runAction(CCRepeatForever::create(seq1)); a2->setTag(1); CCAction *a1 = m_tamara->runAction(CCRepeatForever::create(seq2)); a1->setTag(1); CCAction *a = m_kathia->runAction(CCRepeatForever::create(seq3)); a->setTag(1); schedule(schedule_selector(SpriteEase::testStopAction),6.25f); } void SpriteEase::testStopAction(float dt) { unschedule(schedule_selector(SpriteEase::testStopAction)); m_tamara->stopActionByTag(1); m_kathia->stopActionByTag(1); m_grossini->stopActionByTag(1); } -------------------CCSpeed------------------- void SpeedTest::onEnter() { EaseSpriteDemo::onEnter(); CCSize s = CCDirector::sharedDirector()->getWinSize(); // rotate and jump CCActionInterval *jump1 = CCJumpBy::create(4,ccp(-s.width+80,0),100,4); CCActionInterval *jump2 = jump1->reverse(); CCActionInterval *rot1 = CCRotateBy::create(4,360*2); CCActionInterval *rot2 = rot1->reverse(); CCSequence* seq3_1 = CCSequence::create(jump2,jump1,NULL); CCSequence* seq3_2 = CCSequence::create( rot1,rot2,NULL); CCSpawn* spawn = CCSpawn::create(seq3_1,seq3_2,NULL); //创建速度可改变的动画 CCSpeed* action = CCSpeed::create(CCRepeatForever::create(spawn),1.0f); action->setTag(kTagAction1); CCAction* action2 = (CCAction*)(action->copy()->autorelease()); CCAction* action3 = (CCAction*)(action->copy()->autorelease()); action2->setTag(kTagAction1); action3->setTag(kTagAction1); m_grossini->runAction(action2); m_tamara->runAction(action3); m_kathia->runAction(action); this->schedule(schedule_selector(SpeedTest::altertime),1.0f);//:@selector(altertime:) interval:1.0f]; } void SpeedTest::altertime(float dt) { CCSpeed* action1 = (CCSpeed*)(m_grossini->getActionByTag(kTagAction1)); CCSpeed* action2 = (CCSpeed*)(m_tamara->getActionByTag(kTagAction1)); CCSpeed* action3 = (CCSpeed*)(m_kathia->getActionByTag(kTagAction1)); //设置随机动画速度 action1->setSpeed( CCRANDOM_MINUS1_1() * 2 ); action2->setSpeed( CCRANDOM_MINUS1_1() * 2 ); action3->setSpeed( CCRANDOM_MINUS1_1() * 2 ); }
二、扩展动作
延时: - CCDelayTime 函数调用: - CCCallFunc(无参) - CCCallFuncN(当前对象CCNode) - CCCallfuncND(当前对象,Void指针) -------------------函数调用------------------- void ActionCallFunc::onEnter() { ActionsDemo::onEnter(); centerSprites(3); //执行完动画后调用函数 CCFiniteTimeAction* action = CCSequence::create( CCMoveBy::create(2,ccp(200,0)),CCCallFunc::create(this,callfunc_selector(ActionCallFunc::callback1)),NULL); CCFiniteTimeAction* action2 = CCSequence::create( CCScaleBy::create(2,2),CCFadeOut::create(2),CCCallFuncN::create(this,callfuncN_selector(ActionSequence2::callback2)),NULL); CCFiniteTimeAction* action3 = CCSequence::create( CCRotateBy::create(3,360),CCCallFuncND::create(this,callfuncND_selector(ActionSequence2::callback3),(void*)0xbebabeba),NULL); m_grossini->runAction(action); m_tamara->runAction(action2); m_kathia->runAction(action3); } void ActionCallFunc::callback1() { CCSize s = CCDirector::sharedDirector()->getWinSize(); CCLabelTTF *label = CCLabelTTF::create("callback 1 called","Marker Felt",16); label->setPosition(ccp( s.width/4*1,s.height/2)); addChild(label); } void ActionCallFunc::callback2(CCNode* pSender) { CCSize s = CCDirector::sharedDirector()->getWinSize(); CCLabelTTF *label = CCLabelTTF::create("callback 2 called",16); label->setPosition(ccp( s.width/4*2,s.height/2)); addChild(label); } void ActionCallFunc::callback3(CCNode* pTarget,void* data) { CCSize s = CCDirector::sharedDirector()->getWinSize(); CCLabelTTF *label = CCLabelTTF::create("callback 3 called",16); label->setPosition(ccp( s.width/4*3,s.height/2)); addChild(label); }
三、动作管理器(ActionManager)
维护一个动作表(hash表) CCAction * CCNode::runAction(CCAction* action) { CCAssert( action != NULL,"Argument must be non-nil"); m_pActionManager->addAction(action,this,!m_bRunning); return action; } 利用动作管理器暂停动作,因为动作管理器是全局的,这样就避免第一个类要停止第二个类中的动作需要传递参数的麻烦。 CCDirector* pDirector = CCDirector::sharedDirector(); pDirector->getActionManager()->pauseTarget(pGrossini); pGrossini->runAction(CCRotateBy::create(2,360));
===================================================================
总结:
动画在游戏中占据着举足轻重的位置,必须拿下。
开心一刻:
上农艺课时,老师提问:“什么时候摘西瓜最合适?”一个学生不假思索地回答:“在看瓜人睡熟了的时候。”
【麦可网】Cocos2d-X跨平台游戏开发---教程下载:http://pan.baidu.com/s/1kTio1Av
【麦可网】Cocos2d-X跨平台游戏开发---笔记系列:http://blog.csdn.net/qiulanzhu