zoukankan      html  css  js  c++  java
  • cocos2d-x Action

    转自:http://codingnow.cn/cocos2d-x/775.html

    从结构图可以看出,动作类的基类是CCAction,通过继承它可以实现很多种动作。

      CCFiniteTimeAction有限次动作执行类,就是按时间顺序执行一系列动作,执行完后动作结束;

      CCSpeed:调整实体(节点)的执行速度

      CCFollow:可以使节点跟随指定的另一个节点移动。

    下面我们主要来学习CCFiniteTimeAction,这个类在平常的开发中很常见。

    CCFiniteTimeAction又分为CCActionInstanse(瞬时动作的基类)和CCActionInterval(延时动作的基类)。CCActionInstanse:没什么特别,跟CCActionInterval主要区别是没有执行过程,动作瞬间就执行完成了;CCActionInterval:执行需要一定的时间(或者说一个过程)。我们用的最多的就是延时动作,下面对它进行单独介绍。

    根据上面的类结构图,CCActionInterval的子类有很多,可以通过cocos2d-x自带的tests例子来学习,主要有这些动作:移动(CCMoveTo/CCMoveBy)、缩放(CCScaleTo/CCScaleBy)、旋转(CCRotateTO/CCRotateBy)、扭曲(CCSkewTo/CCSkewBy)、跳跃(CCJumpTo/CCJumpBy)、贝塞尔曲线(CCBezierTo/CCBezierBy)、闪烁(CCBink)、淡入淡出(CCFadeIn/CCFadeOut)、染色(CCTintTo/CCTintBy)等,还可以把上面这些动作的几个组合成一个序列。下面是移动和缩放动作的代码示例,其他的动作都类似,都是调用actionWithDuration函数,用到的时候具体参数的含义可以参考cocos2d-x自带的tests例子。

    CCMoveTo和CCMoveBy
    移动精灵,两者的区别在于:CCMoveTo是移动到指定坐标,CCMoveBy是相对坐标。如ccp(50,50),前者表示移动到x=50,y=50处,后者表示向x方向移动50个单位,向y方向移动50个单位。实例代码如下:

    CCSize winSize = CCDirector::sharedDirector()->getWinSize();
    CCActionInterval* actionMoveTo = CCMoveTo::actionWithDuration(2,ccp(winSize.width - 30,winSize.height - 30) );
    CCActionInterval* actionMoveBy = CCMoveBy::actionWithDuration(1,ccp(-50,-50) );
    //m_Soldier->runAction(actionMoveTo);
    //m_Soldier->runAction(actionMoveBy);
    m_Soldier->runAction( CCSequence::actions(actionMoveTo,actionMoveBy,NULL) );

    CCSequence是动作序列,把若干个动作按顺序组合在一起,然后依次执行,NULL是结束标志。上面代码表示该精灵移动到屏幕右上角,然后沿x轴和y轴负方向移动50个单位。
    CCScaleTo和CCScaleBy
    缩放精灵,前者表示缩放到xx倍;后者表示缩放xx倍。可以分别制定横向和纵向的缩放倍数,实例代码如下:

    CCActionInterval* actionScaleTo = CCScaleTo::actionWithDuration(1, 0.6f);
    CCActionInterval* actionScaleTo2 = CCScaleTo::actionWithDuration(1, 0.6f, 1.5f);
    CCActionInterval* actionScaleBy = CCScaleBy::actionWithDuration(1, 0.4f);
    CCActionInterval* actionScaleBy2 = CCScaleBy::actionWithDuration(1, 0.4f, 2.0f);
    m_Soldier->runAction( actionScaleTo );
    tempSoldier->runAction( CCSequence::actions(actionScaleBy2, actionScaleBy2->reverse(), NULL) );

    reverse()表示执行该动作的逆动作,即恢复到原样。

    接下来学习一下CCSpawn、CCRepeatForever、CCRepeat、CCDelayTime。
    CCSpawn:跟CCSequence不一样的是,它表示将若干个动作组合在一起,同时执行它们(并行执行),执行时间以最长的那个动作为准。下面代码表示:精灵边旋转边跳跃,2秒的时间跳跃4次,每次跳跃的高度是50个单位,沿x轴方向跳跃300个单位的距离;旋转720度。

    CCAction*  action = CCSpawn::actions(
        CCJumpBy::actionWithDuration(2, CCPointMake(300,0), 50, 4),
        CCRotateBy::actionWithDuration( 2,  720),
        NULL);
     
    m_grossini->runAction(action);

    CCRepeatForever:表示无限的重复执行某个动作或动作序列。
    CCRepeat:表示重复执行某个动作或者动作序列,但是是有限次的重复,可以指定重复次数

    CCActionInterval*  act1 = CCRotateTo::actionWithDuration(1, 90);
    CCActionInterval*  act2 = CCRotateTo::actionWithDuration(1, 0);
    CCActionInterval*  seq = (CCActionInterval*)(CCSequence::actions(act1, act2, NULL));
    CCAction*  rep1 = CCRepeatForever::actionWithAction(seq);
    CCActionInterval*  rep2 = CCRepeat::actionWithAction((CCFiniteTimeAction*)(seq->copy()->autorelease()), 10);
     
    m_tamara->runAction(rep1);
    m_kathia->runAction(rep2);

    CCDelayTime:表示延迟,在动作之间加一个间歇时间。如下面的代码表示:精灵执行一个move动作后,暂停2秒,再继续执行后面的move动作。

    CCActionInterval*  move = CCMoveBy::actionWithDuration(1, CCPointMake(150,0));
    CCFiniteTimeAction*  action = CCSequence::actions( move, CCDelayTime::actionWithDuration(2), move, NULL);
     
    m_grossini->runAction(action);

     CCTintTo&CCTintBy 调整某一CCNode对象的rgb色值到某一值

    //通过对象的表态方法create创建对象实例;其中
    //第一参数为渐变时间,第二个参数为RGB中的R值,第三个参数为RGB中的G值,第四个参数为RGB中的B值
    CCActionInterval*  action1 = CCTintTo::create(2, 255, 0, 255);
    CCActionInterval*  action2 = CCTintBy::create(2, -127, -255, -127);
    CCActionInterval*  action2Back = action2->reverse();
    
    m_tamara->runAction( action1);
    m_kathia->runAction( CCSequence::create( action2, action2Back, NULL));

    CCFadeTo:设置某对象的透明度,透明度值为CCRGBAProtocol

    CCFadeIn:通过设置透明度隐藏某对象

    CCFadeOut:通过设置透明度显示某对象

    //第一个参数为闪烁效果的总时间,第二个参数为闪烁的次数
    m_tamara->setOpacity( 0 );
    CCActionInterval*  action1 = CCFadeIn::create(1.0f);
    CCActionInterval*  action1Back = action1->reverse();
    
    CCActionInterval*  action2 = CCFadeOut::create(1.0f);
    CCActionInterval*  action2Back = action2->reverse();
    
    CCActionInterval*  action3 = CCFadeTo::create(2, 20);
    
    m_tamara->runAction( CCSequence::create( action1, action1Back, NULL));
    m_kathia->runAction( CCSequence::create( action2, action2Back, NULL));
    m_grossini->runAction(action3);

    CCCardinalSplineBy–为同一组控制点实现不同的移动路径

    这个类是样条曲线动作,其创建函数CCCardinalSplineBy::create(float duration, cocos2d::CCPointArray *points, float tension);中duration是时间间隔,points是控制点列表,tension是松紧程度。tension==1时,样条线是分段直线。tension<1向外松弛弯曲,tension>1向内缩紧弯曲。By动作是以当前坐标为新坐标原点。

    CCSize s = CCDirector::sharedDirector()->getWinSize();
    CCPointArray *array = CCPointArray::create(20);
    array->addControlPoint(ccp(0, 0));
    array->addControlPoint(ccp(s.width/2-30, 0));
    array->addControlPoint(ccp(s.width/2-30, s.height-80));
    array->addControlPoint(ccp(0, s.height-80));
    array->addControlPoint(ccp(0, 0));
    
        //
        // sprite 1 (By)
        //
        // Spline with no tension (tension==0)
        //
    
    CCCardinalSplineBy *action = CCCardinalSplineBy::create(3, array, 0);
    CCActionInterval *reverse = action->reverse();
    
    CCFiniteTimeAction *seq = CCSequence::create(action, reverse, NULL);
    
    m_tamara->setPosition(ccp(50, 50));
    m_tamara->runAction(seq);
    
        //
        // sprite 2 (By)
        //
        // Spline with high tension (tension==1)
        //
    
    CCCardinalSplineBy *action2 = CCCardinalSplineBy::create(3, array, 1);
    CCActionInterval *reverse2 = action2->reverse();
    
    CCFiniteTimeAction *seq2 = CCSequence::create(action2, reverse2, NULL);
    
    m_kathia->setPosition(ccp(s.width/2, 50));
    m_kathia->runAction(seq2);

    由于By动作是以当前坐标为新坐标原点,所以在draw函数里设置openGL的原点位置

    // move to 50,50 since the "by" path will start at 50,50
    kmGLPushMatrix();
    kmGLTranslatef(50, 50, 0);
    ccDrawCardinalSpline(m_pArray, 0, 100);
    kmGLPopMatrix();
    
    CCSize s = CCDirector::sharedDirector()->getWinSize();
    
    kmGLPushMatrix();
    kmGLTranslatef(s.width/2, 50, 0);
    ccDrawCardinalSpline(m_pArray, 1, 100);
    kmGLPopMatrix();

    动作完成回调

    动作一般支持3种回调方式

    (1).无发送者无数据回调:CCCallFunc,示例如下

    void HelloWorld::actionCallback()
    {
        CCSize winSize = CCDirector::sharedDirector()->getWinSize();
    
        CCLabelTTF *label = CCLabelTTF::labelWithString("Action Callback!", "Marker Felt", 32);
        label->setPosition(ccp(winSize.width / 2, winSize.height / 2));
    
        this->addChild(label);
    }

    (2).有发送者无数据回调:CCCallFuncN  (N是CCNode),示例如下

    void HelloWorld::actionCallbackN(CCNode *pSender)
    {
        CCSprite *sprite = (CCSprite *) pSender;
    
        // 回调变红色
        sprite->setColor(ccRED);
    }

    (3).有发送者有数据回调:CCCallFuncND  (N是CCNode,D是data,是void *类型)

    void HelloWorld::actionCallbackND(CCNode *pSender, void *data)
    {
        CCSize winSize = CCDirector::sharedDirector()->getWinSize();
    
        CCSprite *sprite = (CCSprite *) pSender;
    
        // 回调变蓝色
        sprite->setColor(ccBLUE);
        
        // 接收回调数据
        CCLabelTTF *label = CCLabelTTF::labelWithString((char *) data, "Marker Felt", 32);
        label->setPosition(ccp(winSize.width / 2, winSize.height / 2));
        this->addChild(label);
    
        CCLog((char *) data);
    }

    使用回调示例如下:

    void HelloWorld::actionListen()
    {
        CCSize winSize = CCDirector::sharedDirector()->getWinSize();
    
        CCFiniteTimeAction *action = CCSequence::actions(
            CCMoveBy::actionWithDuration(2.0f, CCPointMake(winSize.width / 2, 0)),
            CCCallFunc::actionWithTarget(this, callfunc_selector(HelloWorld::actionCallback)), NULL);
    
        CCFiniteTimeAction *actionN = CCSequence::actions(
            CCMoveBy::actionWithDuration(2.0f, CCPointMake(-winSize.width / 2, 0)),
            CCCallFuncN::actionWithTarget(this, callfuncN_selector(HelloWorld::actionCallbackN)), NULL);
    
        CCFiniteTimeAction *actionND = CCSequence::actions(
            CCMoveBy::actionWithDuration(2.0f, CCPointMake(winSize.width / 2, 0)),
            CCCallFuncND::actionWithTarget(this, callfuncND_selector(HelloWorld::actionCallbackND), (void *) "Callback Data"), NULL);
    
        oldManSprite->runAction(actionND);
        youngSisterSprite->runAction(actionN);
    }
  • 相关阅读:
    OnEraseBkgnd、OnPaint与画面重绘
    .编译ADO类DLL时报错的解决方案
    VC列表框样式
    Codeforces 131D. Subway 寻找环树的最短路径
    Codeforces 103B. Cthulhu 寻找奈亚子
    Codeforces 246D. Colorful Graph
    Codeforces 278C. Learning Languages 图的遍历
    Codeforces 217A. Ice Skating 搜索
    Codeforces 107A. Dorm Water Supply 搜图
    Codeforces 263 D. Cycle in Graph 环
  • 原文地址:https://www.cnblogs.com/sevenyuan/p/3178642.html
Copyright © 2011-2022 走看看