【麦可网】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, 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,0);
pLabel->runAction(tintto);
CCTintBy *tintby = CCTintBy::create(3.0f,255,0,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,255,0,0);
CCFadeOut *fadeout = CCFadeOut::create(3.0f);
CCFiniteTimeAction *sequence = CCSequence::create(tintto,fadeout,NULL);
pLabel->runAction(sequence);
------------------CCSpawn------------------
CCTintTo *tintto = CCTintTo::create(3.0f,255,0,0);
CCFadeOut *fadeout = CCFadeOut::create(3.0f);
CCFiniteTimeAction *spawn = CCSpawn::create(tintto,fadeout,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, 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);
------------------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,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, CCCA(delay), move_ease_in_back, CCCA(delay), NULL);
CCSequence* seq3 = CCSequence::create(move_ease_out, CCCA(delay), move_ease_out_back, CCCA(delay), 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),
CCFadeOut::create(2),
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", "Marker Felt", 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", "Marker Felt", 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.youkuaiyun.com/qiulanzhu