【麦可网】Cocos2d-X跨平台游戏开发学习笔记---第十七课:Cocos2D-X动作行为1-5

【麦可网】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.csdn.net/qiulanzhu



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值