Cocos2d-x 动作之动作原理——CCActionManager的工作原理

来源:互联网 发布:淘宝优惠微信群二维码 编辑:程序博客网 时间:2024/05/18 03:11

学习了CCAction在每一帧中如何被更新之后,我们不妨回头看看动作管理类CCActionManager的工作原理。在对CCDirector进行初始化时,也会对CCActionManager进行初始化。下面的代码是CCDirector::init()方法中的一部分:

//动作管理器m_pActionManager = new CCActionManager();m_pScheduler->scheduleUpdateForTarget(m_pActionManager, kCCPrioritySystem, false);

可以看到,在CCActionManager被初始化后,马上就调用了定时调度器CCSchedulerscheduleUpdateForTarget方法。在scheduleUpdateForTarget函数中,我们为CCActionManager注册了一个定期更新的服务,这意味着动作的调度与定时器的调度都统一受到CCScheduler的控制。具体地说,我们可以方便地同时暂停或恢复定时器与动作的运行,而不必考虑它们不同步的问题。

CCScheduler在每一帧更新时,都会触发CCActionManager注册的update方法。从下面给出的CCActionManager::update方法的代码可以看到,CCActionManager在这时对每一个动作都进行了更新。与调度器CCScheduler类似的一点是,为了防止动作调度过程中所遍历的表被修改,Cocos2d-x对动作的删除进行了仔细地处理,保证任何情况下都可以安全地删除动作:

void CCActionManager::update(float dt){    //枚举动作表中的每一个目标节点    for (tHashElement *elt = m_pTargets; elt != NULL; )    {        m_pCurrentTarget = elt;        m_bCurrentTargetSalvaged = false;        if (! m_pCurrentTarget->paused)        {            //枚举目标节点对应的每一个动作            //actions数组可能会在循环中被修改,因此需要谨慎处理            for (m_pCurrentTarget->actionIndex = 0;                 m_pCurrentTarget->actionIndex < m_pCurrentTarget->actions->num;                m_pCurrentTarget->actionIndex++)            {                m_pCurrentTarget->currentAction =                     (CCAction*)m_pCurrentTarget->actions                        ->arr[m_pCurrentTarget->actionIndex];                if (m_pCurrentTarget->currentAction == NULL)                {                    continue;                }                m_pCurrentTarget->currentActionSalvaged = false;                m_pCurrentTarget->currentAction->step(dt);   //触发动作更新                if (m_pCurrentTarget->currentActionSalvaged)                {                    m_pCurrentTarget->currentAction->release();                }                 else if (m_pCurrentTarget->currentAction->isDone())                {                    m_pCurrentTarget->currentAction->stop();                    CCAction *pAction = m_pCurrentTarget->currentAction;                    m_pCurrentTarget->currentAction = NULL;                    removeAction(pAction);                }                m_pCurrentTarget->currentAction = NULL;            }        }        elt = (tHashElement*)(elt->hh.next);        if (m_bCurrentTargetSalvaged && m_pCurrentTarget->actions->num == 0)        {            deleteHashElement(m_pCurrentTarget);        }    }    m_pCurrentTarget = NULL;}