3.X:ActionManager动作管理类浅析:

1、Action类继承关系图,虽然这张图是2.X的版本,以为没找到3.X的这种图,

但是整体来说是一样的,CCFiniteTimeAction又分为CCActionInstanse(瞬时动作的基类)和CCActionInterval(延时动作的基类)


2、
动作管理类分析:
动作管理类,我们一般不需要直接使用,如果要是使用摸个动作,直接使用Node中的方法即可。

3、整个动作的管理,跟下面这个结构密不可分
//
// singleton stuff
//
typedef struct _hashElement
{
    struct _ccArray     *actions; //一个Node上,可能又很多个action
    Node                *target; //Node
    int                 actionIndex; 
    Action              *currentAction; //当前的Action
    bool                currentActionSalvaged; //是否被标记
    bool                paused; //是否暂停
    UT_hash_handle      hh; //hashTable
} tHashElement;

4、
// main loop
//这个update方法在每次循环的时候都会被调用,所有动作的执行处理,都是在这个函数中。
void ActionManager::update(float dt)
{
    for (tHashElement *elt = _targets; elt != nullptr; )
    {
        _currentTarget = elt;
        _currentTargetSalvaged = false;

        if (! _currentTarget->paused)
        {
// The 'actions' MutableArray may change while inside this loop.
//这里循环Node的所有Action,因为一个Node可能又很多个Action
            for (_currentTarget->actionIndex = 0; _currentTarget->actionIndex < _currentTarget->actions->num;
                _currentTarget->actionIndex++)
            {
                _currentTarget->currentAction = (Action*)_currentTarget->actions->arr[_currentTarget->actionIndex];
                if (_currentTarget->currentAction == nullptr)
                {
                    continue;
                }

                _currentTarget->currentActionSalvaged = false;
				//执行Action的step方法,这个方法会被继承自Action的具体动作类重写,
如:(1)ActionInterval是有一段持续时间的动作
void ActionInterval::step(float dt)
{
    if (_firstTick)
    {
        _firstTick = false;
        _elapsed = 0;
    }
    else
    {
        _elapsed += dt;
    }
    //这里调用update方法,更新动作,如MoveTo,需要更新坐标,位置等等
    this->update(MAX (0,                                  // needed for rewind. elapsed could be negative
                      MIN(1, _elapsed /
                          MAX(_duration, FLT_EPSILON)   // division by 0
                          )
                      )
                 );
}
(2) 
ActionInstant是立即执行的动作,这里就直接调用update
void ActionInstant::step(float dt) {
    CC_UNUSED_PARAM(dt);
    update(1);
}


                _currentTarget->currentAction->step(dt);

                if (_currentTarget->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.
                    _currentTarget->currentAction->release();
                } else
//判断是否结束,如果结束,就stop,并且从Node的Action数组中移除。
                if (_currentTarget->currentAction->isDone())
                {
                    _currentTarget->currentAction->stop();

                    Action *action = _currentTarget->currentAction;
                    // Make currentAction nil to prevent removeAction from salvaging it.
                    _currentTarget->currentAction = nullptr;
                    removeAction(action);
                }

                _currentTarget->currentAction = nullptr;
            }
        }

        // 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 (_currentTargetSalvaged && _currentTarget->actions->num == 0)
        {
            deleteHashElement(_currentTarget);
        }
    }

    // issue #635
    _currentTarget = nullptr;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值