关于 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执行当前动作。


			

                        优质内容筛选与推荐>>
1、Android Fragment+ViewPager实现循环滑动
2、NO.5 线程范围内共享变量的概念与作用(一)
3、Windows Server 2008壮烈牺牲
4、生成流水号方法
5、剪切板


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn