_鞋男原创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的机制是一样的