关于 cocos2dx 动画内部管理
cocos2dx 动画基类:CCAction.其下主要包含限时动画(finitetime aciton)
finitetime aciton主要分为两类动画,瞬时动画(instant action)和时段动画(interval action),其中instant action 有CCShow,CCHide
CCRemoveSelf,CCCallFunc等,interval action有CCMove,CCRotate,CCSkew,CCJump,CCTint,CCScale,CCAnimate等。
1.动画的管理
动画的运行通过类CCActionManager予以管理,每一个基于CCNode的节点都有一个CCActionManager对象,而这个对象来自CCDirector:
CCNode::CCNode(void) ... { // set default scheduler and actionManager CCDirector *director = CCDirector::sharedDirector(); m_pActionManager = director->getActionManager(); m_pActionManager->retain(); m_pScheduler = director->getScheduler(); m_pScheduler->retain(); ... }
动画播放时间控制是统一放在CCDirector中实现:
bool CCDirector::init(void) { ... // scheduler m_pScheduler = new CCScheduler(); // action manager m_pActionManager = new CCActionManager(); m_pScheduler->scheduleUpdateForTarget(m_pActionManager, kCCPrioritySystem, false); ... return true; }
而m_pActionManager的更新(update)实际上是由CCDirector中成员CCScheduler对象m_pScheduler的更新(update)调用触发(
kCCPrioritySystem<0,故m_pActionManager添加至hthash数据结构m_pUpdatesNegList;游戏主循环最终来自os定时器,如ios的CADisplayLink):
// main loop void CCScheduler::update(float dt) { ... // updates with priority < 0 DL_FOREACH_SAFE(m_pUpdatesNegList, pEntry, pTmp) { if ((! pEntry->paused) && (! pEntry->markedForDeletion)) { pEntry->target->update(dt); } } ... }
当一个基于CCNode的节点运行一个action时:
CCAction * CCNode::runAction(CCAction* action) { CCAssert( action != NULL, "Argument must be non-nil"); m_pActionManager->addAction(action, this, !m_bRunning); return action; }
void CCActionManager::addAction(CCAction *pAction, CCNode *pTarget, bool paused) {
... pElement = (tHashElement*)calloc(sizeof(*pElement), 1); pElement->paused = paused; pTarget->retain(); pElement->target = pTarget; HASH_ADD_INT(m_pTargets, target, pElement); ... }
以上操作将要运行的action添加至actionManager所管理的一个hthash数据结构m_pTargets。当游戏循环更新时,CCActionManager,update会被调用
// main loop void CCActionManager::update(float dt) { for (tHashElement *elt = m_pTargets; elt != NULL; ) { m_pCurrentTarget = elt; ...
m_pCurrentTarget->currentAction->step(dt); ... } ... }
在这里前面所添加的action将会遍历,通过step执行当前动作。
优质内容筛选与推荐>>