cocos2dx 中的动作机制 动作在引擎中的行为

_鞋男原创BLOG:http://www.jb51.cc/article/p-uxhebemw-bbq.html


在cocos2dx 2.x中:runAction的函数

CCAction * CCNode::runAction(CCAction* action)
{
    CCAssert( action != NULL,"Argument must be non-nil");
    m_pActionManager->addAction(action,this,!m_bRunning);
    return action;
}
由此可见,但凡继承自CCNode的都具有行为。
CCActionManager *m_pActionManager;  ///< a pointer to ActionManager singleton,which is used to handle all the actions  
其实就是
CCDirector *director = CCDirector::sharedDirector();
m_pActionManager = director->getActionManager();

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);//还有这句
}

void ccArrayAppendobject(ccArray *arr,CCObject* object)
{
    CCAssert(object != NULL,"Invalid parameter!");
    object->retain();
	arr->arr[arr->num] = object;
	arr->num++;
}
数据结构
typedef struct _hashElement
{
    struct _ccArray             *actions;
    CCObject                    *target;
    unsigned int                actionIndex;
    CCAction                    *currentAction;
    bool                        currentActionSalvaged;
    bool                        paused;
    UT_hash_handle                hh;
} tHashElement;
通过pElement将Target和pAction配对
void CCAction::startWithTarget(CCNode *aTarget)
{
    m_pOriginalTarget = m_pTarget = aTarget;
}
将个action打上了标签,谁的action,绑定了执行者

以上就是对象的动作算是注册到了引擎了,现在看引擎怎么个程序。

在每帧绘制场景(drawScene)的时候会根据时间调度(schedule),刷新界面(updata).

void CCActionManager::update(float dt)
{
 for (tHashElement *elt = m_pTargets; elt != NULL; )
 {
 m_pCurrentTarget = elt;
 m_bCurrentTargetSalvaged = false;

 if (! m_pCurrentTarget->paused)
 {
 // The 'actions' CCMutableArray may change while inside this loop.
 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)
 {
 // The currentAction told the node to remove it. To prevent the action from
 // accidentally deallocating itself before finishing its step,we retained
 // it. Now that step is done,it's safe to release it.
 m_pCurrentTarget->currentAction->release();
 } else
 if (m_pCurrentTarget->currentAction->isDone())
 {
 m_pCurrentTarget->currentAction->stop();

 CCAction *pAction = m_pCurrentTarget->currentAction;
 // Make currentAction nil to prevent removeAction from salvaging it.
 m_pCurrentTarget->currentAction = NULL;
 removeAction(pAction);
 }

 m_pCurrentTarget->currentAction = NULL;
 }
 }

 // elt,at this moment,is still valid
 // so it is safe to ask this here (issue #490)
 elt = (tHashElement*)(elt->hh.next);

 // only delete currentTarget if no actions were scheduled during the cycle (issue #481)
 if (m_bCurrentTargetSalvaged && m_pCurrentTarget->actions->num == 0)
 {
 deleteHashElement(m_pCurrentTarget);
 }
 }

 // issue #635
 m_pCurrentTarget = NULL;
}
哈希什么的不大懂啊,m_pTargets存放的是一个结构体tHashElement对象
HASH_ADD_INT(m_pTargets,pElement);
这里调用太深了,
m_pCurrentTarget->currentAction->step(dt);
这步将会调用到具体的Action的step,
接下来大家可以看我转载的一篇,懒得写了 2.x和3.x的机制是一样的

Cocos2dx 3.0游戏开发找小三之Cocos2d-x的动作机制:嘻,善哉!技盖至此乎?

相关文章

    本文实践自 RayWenderlich、Ali Hafizji 的文章《...
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@1...
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从C...
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发...
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《...
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试...