Cocos2d-x 动作之动作原理——动作的更新

来源:互联网 发布:错题本软件 编辑:程序博客网 时间:2024/05/21 07:01

在了解了CCActionCCFiniteTimeActionCCActionInterval的类结构后,下面我们以它们为例分析Cocos2d-x的动作机制。

当我们对CCNode调用runAction(CCAction* action)方法时,动作管理类CCActionManager(它是一个单例对象)会将新的CCAction和对应的目标节点添加到其管理的动作表中。

CCActionManageraddAction方法中,我们将动作添加到动作队列之后,就会对该CCAction调用成员函数startWithTarget(CCNode* pTarget)来绑定该动作的执行者。而在CCAction的子类中(如CCActionInterval),还初始化了一些参数:

void CCActionInterval::startWithTarget(CCNode *pTarget){    CCFiniteTimeAction::startWithTarget(pTarget);    m_elapsed = 0.0f;    m_bFirstTick = true;}

当这些准备工作都完成后,每一帧刷新屏幕时,系统都会在CCActionManager中遍历其动作表中的每一个动作,并调用该动作的step(ccTimedt)方法。step方法主要负责计算m_elapsed的值,并调用update(float time)方法,相关代码如下:

void CCActionInterval::step(float dt){    if (m_bFirstTick)    {        m_bFirstTick = false;        m_elapsed = 0;    }    else    {        m_elapsed += dt;    }    this->update(MAX (0,        MIN(1, m_elapsed / MAX(m_fDuration, FLT_EPSILON))        )    );}

传入update方法的time参数表示逝去的时间与动作完成需要的时间的比值,是介于0和1之间的一个数,即动作完成的百分比。

CCActionInterval并没有进一步实现update方法。下面我们继续以继承自CCActionIntervalCCRotateTo动作的update方法为例,分析update函数是如何实现的,其实现代码如下:

void CCRotateTo::update(float time){    if (m_pTarget)    {        m_pTarget->setRotation(m_fStartAngle + m_fDiffAngle * time);    }}

看到这里,我们已经能看出Cocos2d-x的动作机制的整个工作流程了。在CCRotateTo中,最终完成的操作是修改目标节点的Rotation属性值,更新该目标节点的旋转属性值。

最后,在每一帧刷新结束后,在CCActionManager类的update方法中都会检查动作队列中每一个动作的isDone函数是否返回true。如果返回true,则动作已完成,将其从队列中删除。isDone函数的代码如下:

bool CCActionInterval::isDone(void){    return m_elapsed >= m_fDuration;}

对于不同的动作类,虽然整体流程大致都是先调用step方法,然后按照各个动作的具体定义来更新目标节点的属性,但是不同动作的具体实现会有所不同。例如,CCRepeatForever动作的isDone函数始终返回false,因为它是永远在执行的动作;又如CCActionInstant及其子类的step函数中,向update传递的参数值始终是1,因为瞬时动作会在下一帧刷新后完成,不需要多次执行update

原创粉丝点击