Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / 剖析cocos2d-x之Action实现

稍微了解cocos2d-x的朋友应该都知道cocos2d-x里面的动作都是通过CCAction的各种派生类来实现的。
 
比如我要将一个Sprite在1秒内从(0,0)移动到(400,400)
 
pSprite->setPosition(ccp(0,0));
 
CCMoveTo* moveTo = CCMoveTo::create(1.0f,,ccp(400,400));
 
pSprite->runAction(moveTo);那么,让我们来看看Action在cocos2d-x到底是如何实现的。
 
首先必须要了解的几个类
 
1.CCAction和CCActionInterval
 
CCAction是所有动作的基类,从代码里可以看出它本身并不执行动作
 
void CCAction::update(float time)
 
{
 
    CC_UNUSED_PARAM(time);
 
    CCLOG("[Action update]. override me");
 
}
 
他的作用只是提供一部分接口,如stop,update等等,其本身的实际作用并不是太大CCActionInterval反而相对重要些,这个是大部分常用动作的基类,如常用的CCMoveTo,CCRotateBy等都是继承自CCActionInterval,CCActionInterval还有很重要的一点就是他实现了step方法,这个方法是大部分其派生类更新动作的基础(后文会有讨论)2.CCActionManager
 
从名字可以看出,这个类负责管理着所有的动作,
 
前面代码里的pSprite->runAction(moveTo);其实就是将moveTo这个Action和pSprite这个Node加入到了CCActionManager内部维护的m_pTargets的这个hash表中
 
看看代码: CCAction * CCNode::runAction(CCAction* action)
{
    CCAssert( action != NULL, "Argument must be non-nil");
    m_pActionManager->addAction(action, this, !m_bIsRunning);
    return action;
}看看,内部是否是调用CCActionManager的addAction
 
接着我们再看看addAction的实现 void CCActionManager::addAction(CCAction *pAction, CCNode *pTarget, bool paused)
{
    CCAssert(pAction != NULL, "");
    CCAssert(pTarget != NULL, "");

    tHashElement *pElement = NULL;
    // we should convert it to CCObject*, because we save it as CCObject*
    CCObject *tmp = pTarget;
    HASH_FIND_INT(m_pTargets, &tmp, pElement);
    if (! pElement)
    {
        pElement = (tHashElement*)calloc(sizeof(*pElement), 1);
        pElement->paused = paused;
        pTarget->retain();
        pElement->target = pTarget;
        HASH_ADD_INT(m_pTargets, target, pElement);
    }


   actionAllocWithHashElement(pElement);

   CCAssert(! ccArrayContainsObject(pElement->actions, pAction), "");
   ccArrayAppendObject(pElement->actions, pAction);

   pAction->startWithTarget(pTarget);
}