cocos2d-x学习笔记(四)动作(Action)

时间:2023-02-06 15:55:58

cocos2d-x引擎中,动作(Action)定义了在节点上的通用操作,他不依赖于节点,但是
在运行时需要指定节点为目标,动作最直观的好处就是可以实现很多动画效果,如精灵的行走、
跳跃等

 

CCAction是所有动作的基类:

cocos2d-x学习笔记(四)动作(Action)

 

CCSpeed:调整实体(节点)的执行速度;CCFollow:可以使节点跟随指定的另一个节点移动

 

瞬时动作(CCActionInstant)与延时动作(CCActionInterval):

瞬时动作的主要特点就是不需要花费时间,瞬间就能完成动作的执行,这些动作的基类为CCActionInstant

延时动作的主要特点就是执行动作需要花费一定的时间,这些动作的基类为CCActionInterval

 

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

void ActionsDemo::onEnter()  //场景加载时的回调函数
{
    CCLayer::onEnter();

    // Or you can create an sprite using a filename. only PNG is supported now. Probably TIFF too
    m_grossini = CCSprite::create(s_pPathGrossini);
    m_grossini->retain();

    m_tamara = CCSprite::create(s_pPathSister1); 
    m_tamara->retain();

    m_kathia = CCSprite::create(s_pPathSister2);
    m_kathia->retain();

    addChild(m_grossini, 1);
    addChild(m_tamara, 2);
    addChild(m_kathia, 3);

    m_grossini->setPosition(ccp(VisibleRect::center().x, VisibleRect::bottom().y+VisibleRect::getVisibleRect().size.height/3));
    m_tamara->setPosition(ccp(VisibleRect::center().x, VisibleRect::bottom().y+VisibleRect::getVisibleRect().size.height*2/3));
    m_kathia->setPosition(ccp(VisibleRect::center().x, VisibleRect::bottom().y+VisibleRect::getVisibleRect().size.height/2)); 

    // add title and subtitle
    std::string str = title();
    const char * pTitle = str.c_str();
    CCLabelTTF* label = CCLabelTTF::create(pTitle, "Arial", 18);
    addChild(label, 1);
    label->setPosition( ccp(VisibleRect::center().x, VisibleRect::top().y - 30) );

    std::string strSubtitle = subtitle();
    if( ! strSubtitle.empty() ) 
    {
        CCLabelTTF* l = CCLabelTTF::create(strSubtitle.c_str(), "Thonburi", 22);
        addChild(l, 1);
        l->setPosition( ccp(VisibleRect::center().x, VisibleRect::top().y - 60) );
    }    

    // add menu
    CCMenuItemImage *item1 = CCMenuItemImage::create(s_pPathB1, s_pPathB2, this, menu_selector(ActionsDemo::backCallback) );
    CCMenuItemImage *item2 = CCMenuItemImage::create(s_pPathR1, s_pPathR2, this, menu_selector(ActionsDemo::restartCallback) );
    CCMenuItemImage *item3 = CCMenuItemImage::create(s_pPathF1, s_pPathF2, this, menu_selector(ActionsDemo::nextCallback) );

    CCMenu *menu = CCMenu::create(item1, item2, item3, NULL);

    menu->setPosition(CCPointZero);
    item1->setPosition(ccp(VisibleRect::center().x - item2->getContentSize().width*2, VisibleRect::bottom().y+item2->getContentSize().height/2));
    item2->setPosition(ccp(VisibleRect::center().x, VisibleRect::bottom().y+item2->getContentSize().height/2));
    item3->setPosition(ccp(VisibleRect::center().x + item2->getContentSize().width*2, VisibleRect::bottom().y+item2->getContentSize().height/2));

    addChild(menu, 1);
}


 

void ActionsDemo::onExit()  //场景结束时的回调函数
{
    m_grossini->release();  //在onEnter()中调用retain()的对象需要在这里释放
    m_tamara->release();
    m_kathia->release();

    CCLayer::onExit();  //必须调用父类的onExit否则内存泄漏
}


 

void ActionMove::onEnter()
{
    ActionsDemo::onEnter();

    centerSprites(3);

    CCSize s = CCDirector::sharedDirector()->getWinSize();

    CCActionInterval*  actionTo = CCMoveTo::create(2, ccp(s.width-40, s.height-40)); //移动到(s.width-40,s.height-40)
    CCActionInterval*  actionBy = CCMoveBy::create(2, ccp(80,80)); //当前点移动(80,80),而不是移动到(80,80)
    CCActionInterval*  actionByBack = actionBy->reverse(); //做相反的动作

    m_tamara->runAction( actionTo); //执行动画
    m_grossini->runAction( CCSequence::create(actionBy, actionByBack, NULL));
    m_kathia->runAction(CCMoveTo::create(1, ccp(40,40)));
}


CCSequence是动作序列,把若干个动作按顺序组合在一起,然后依次执行,NULL是结束标志。
reverse()表示执行该动作的逆动作,即恢复到原样。

以此类推其它的动作基本差不多,可以参考TestCpp例子:

如:CCScaleTo和CCScaleBy
缩放精灵,前者表示缩放到xx倍;后者表示缩放xx倍

 

CCSpawn:跟CCSequence不一样的是,它表示将若干个动作组合在一起,同时执行它们,执行时间以最长的那个动作为准

精灵边旋转边跳跃,2秒的时间跳跃4次,每次跳跃的高度是50个单位,沿x轴方向跳跃300个单位的距离;旋转720度。

void ActionSpawn::onEnter()
{
    ActionsDemo::onEnter();

    alignSpritesLeft(1);


    CCAction*  action = CCSpawn::create(
        CCJumpBy::create(2, ccp(300,0), 50, 4),
        CCRotateBy::create( 2,  720),
        NULL);

    m_grossini->runAction(action);
}


CCRepeatForever:表示无限的重复执行某个动作或动作序列:

void ActionRepeatForever::repeatForever(CCNode* pSender)
{
    CCRepeatForever *repeat = CCRepeatForever::create( CCRotateBy::create(1.0f, 360) );

    pSender->runAction(repeat);
}


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


 

void ActionRotateToRepeat::onEnter()
{
    ActionsDemo::onEnter();

    centerSprites(2);

    CCActionInterval*  act1 = CCRotateTo::create(1, 90);
    CCActionInterval*  act2 = CCRotateTo::create(1, 0);
    CCActionInterval*  seq = (CCActionInterval*)(CCSequence::create(act1, act2, NULL));
    CCActionInterval*  rep2 = CCRepeat::create((CCFiniteTimeAction*)(seq->copy()->autorelease()), 10); //有限重复
    m_kathia->runAction(rep2);
}


 

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

void ActionDelayTime::onEnter()
{
    ActionsDemo::onEnter();

    alignSpritesLeft(1);

    CCActionInterval*  move = CCMoveBy::create(1, ccp(150,0));
    CCFiniteTimeAction*  action = CCSequence::create( move, CCDelayTime::create(2), move, NULL);

    m_grossini->runAction(action);
}