cocos2dx看懂CCAnimate

来源:互联网 发布:数据分析师考试试题 编辑:程序博客网 时间:2024/05/16 15:55

 


 CCAnimate源码如下:

 

class CCTexture2D;//序列帧动画class CC_DLL CCAnimate : public CCActionInterval{public://构造与析构。    CCAnimate();    ~CCAnimate();    //初始化动画。    bool initWithAnimation(CCAnimation *pAnimation);//重载基类的相应函数。     virtual CCObject* copyWithZone(CCZone* pZone);    virtual void startWithTarget(CCNode *pTarget);    virtual void stop(void);    virtual void update(float t);    virtual CCActionInterval* reverse(void);public:    //创建一个序列帧动画,内部调用create实现。参数为动画信息结构指针。    CC_DEPRECATED_ATTRIBUTE static CCAnimate* actionWithAnimation(CCAnimation *pAnimation);        //创建一个序列帧动画。    static CCAnimate* create(CCAnimation *pAnimation);        //定义一个动画信息结构指针变量以及存取此变量的函数。    CC_SYNTHESIZE_RETAIN(CCAnimation*, m_pAnimation, Animation)protected://保存每一帧要切换时的进度的容器指针,由动画信息结构指针取得。std::vector<float>* m_pSplitTimes;//当前要播放的下一帧序号。    int m_nNextFrame;//各帧中保存的精灵信息。    CCSpriteFrame*  m_pOrigFrame;//循环次数。    unsigned int m_uExecutedLoops;};
 //创建一个序列帧动画,内部调用create实现。参数为动画信息结构。CCAnimate* CCAnimate::actionWithAnimation(CCAnimation *pAnimation){    return CCAnimate::create(pAnimation);}//创建一个序列帧动画。CCAnimate* CCAnimate::create(CCAnimation *pAnimation){//创建,初始化,交由内存管理器,包邮~    CCAnimate *pAnimate = new CCAnimate();    pAnimate->initWithAnimation(pAnimation);    pAnimate->autorelease();        //返回创建的实例对象。    return pAnimate;}
//初始化序列动画。bool CCAnimate::initWithAnimation(CCAnimation *pAnimation){//有效性判断。    CCAssert( pAnimation!=NULL, "Animate: argument Animation must be non-NULL");//取得序列的时长。    float singleDuration = pAnimation->getDuration();//乘以循环次数做为当前动画总时长来进行初始化。    if ( CCActionInterval::initWithDuration(singleDuration * pAnimation->getLoops() ) ) {//初始化变量。        m_nNextFrame = 0;                 //将参数pAnimation保存到动画信息结构指针变量m_pAnimation.        setAnimation(pAnimation);        m_pOrigFrame = NULL;        m_uExecutedLoops = 0;//设置容器大小。这里我认为应该写成resize而不是reserver!!!        m_pSplitTimes->reserve(pAnimation->getFrames()->count());        //初始化变量。        float accumUnitsOfTime = 0; //序列播放一轮的时间/        float newUnitOfTimeValue = singleDuration / pAnimation->getTotalDelayUnits();//取得序列信息中的帧信息数组。        CCArray* pFrames = pAnimation->getFrames();//        CCARRAY_VERIFY_TYPE(pFrames, CCAnimationFrame*);//定义临时变量pObj来遍历取得帧信息中的单帧信息。        CCObject* pObj = NULL;        CCARRAY_FOREACH(pFrames, pObj)        { //取得单帧信息。            CCAnimationFrame* frame = (CCAnimationFrame*)pObj; //计算播放当前单帧时的进度。            float value = (accumUnitsOfTime * newUnitOfTimeValue) / singleDuration;            accumUnitsOfTime += frame->getDelayUnits(); //将当前单帧的进度存入容器。            m_pSplitTimes->push_back(value);        }    //返回成功。        return true;}//如果初始化失败,返回false。    return false;}
//创建拷贝。CCObject* CCAnimate::copyWithZone(CCZone *pZone){    CCZone* pNewZone = NULL;    CCAnimate* pCopy = NULL;    if(pZone && pZone->m_pCopyObject)     {        //in case of being called at sub class        pCopy = (CCAnimate*)(pZone->m_pCopyObject);    }    else    {        pCopy = new CCAnimate();        pZone = pNewZone = new CCZone(pCopy);    }    CCActionInterval::copyWithZone(pZone);    pCopy->initWithAnimation((CCAnimation*)m_pAnimation->copy()->autorelease());    CC_SAFE_DELETE(pNewZone);    return pCopy;}
//构造,注意在这里申请了一个vector<float>容器,并将成员指针变量m_pSplitTimes指向它的。CCAnimate::CCAnimate(): m_pAnimation(NULL), m_pSplitTimes(new std::vector<float>), m_nNextFrame(0), m_pOrigFrame(NULL), m_uExecutedLoops(0){}
//析构。CCAnimate::~CCAnimate(){    CC_SAFE_RELEASE(m_pAnimation);    CC_SAFE_RELEASE(m_pOrigFrame);    CC_SAFE_DELETE(m_pSplitTimes);}
//设置演示当前序列动画的演员。void CCAnimate::startWithTarget(CCNode *pTarget){//先调用基类的相应函数。    CCActionInterval::startWithTarget(pTarget);//序列帧动画必须是个精灵。    CCSprite *pSprite = (CCSprite*)(pTarget);//释放上一个    CC_SAFE_RELEASE(m_pOrigFrame);//如果有帧数据。    if (m_pAnimation->getRestoreOriginalFrame())    { //取得精灵的帧信息。         m_pOrigFrame = pSprite->displayFrame();                 //对帧信息占用,引用数加一。         m_pOrigFrame->retain();    }    m_nNextFrame = 0;    m_uExecutedLoops = 0;}//停止当前动画。void CCAnimate::stop(void){//如果动画有帧数据且有演员。    if (m_pAnimation->getRestoreOriginalFrame() && m_pTarget)    {        //设置演员显示当前帧。        ((CCSprite*)(m_pTarget))->setDisplayFrame(m_pOrigFrame);    }        //停止当前动画。    CCActionInterval::stop();}//更新动画。
oid CCAnimate::update(float t){// 如果整个动画未播放,先计算循环是否够次数。     if( t < 1.0f ) {        //计算出当前进度播放的循环数。         t *= m_pAnimation->getLoops();                 // 通过先取整再判断是否大于当前的已经循环次数来判断是否是新的循环,如果是将下一帧置零,已经循环的次数加1 。         unsigned int loopNumber = (unsigned int)t;        if( loopNumber > m_uExecutedLoops ) {            m_nNextFrame = 0;            m_uExecutedLoops++;        }        // 对t进行浮点取模值,将其限制在0~1之间,这样等于又转换成为了当前动画播放的进度值。        t = fmodf(t, 1.0f);    }        //取得动画的帧信息容器和帧数。     CCArray* frames = m_pAnimation->getFrames();    unsigned int numberOfFrames = frames->count();    //精灵图片信息。CCSpriteFrame *frameToDisplay = NULL;        //找出要播放的帧图片设置为精灵要显示的图片,这里用了一个for循环。从下一帧开始到结束帧进行遍历,判断是否到了这一帧。for( unsigned int i=m_nNextFrame; i < numberOfFrames; i++ ) {         //取出循环中的当前帧的播出时间进度。        float splitTime = m_pSplitTimes->at(i);                //如果这一帧的进度小于当前动画的播放进度,即代表进入了这一帧。        if( splitTime <= t ) {                        //取得对应的动画帧信息。            CCAnimationFrame* frame = (CCAnimationFrame*)frames->objectAtIndex(i);                         //取得当前帧的精灵图片信息。            frameToDisplay = frame->getSpriteFrame();                         //设置为精灵的当前显示图片。            ((CCSprite*)m_pTarget)->setDisplayFrame(frameToDisplay);                         //通过动画帧信息取得其字典信息。            CCDictionary* dict = frame->getUserInfo();            if( dict )            {                                  //忽略了。                //TODO: [[NSNotificationCenter defaultCenter] postNotificationName:CCAnimationFrameDisplayedNotification object:target_ userInfo:dict];            }                         //帧数加一。            m_nNextFrame = i+1;            break;        }    }}
//创建一个反向播放的序列帧动画。CCActionInterval* CCAnimate::reverse(void){    CCArray* pOldArray = m_pAnimation->getFrames();    CCArray* pNewArray = CCArray::createWithCapacity(pOldArray->count());       CCARRAY_VERIFY_TYPE(pOldArray, CCAnimationFrame*);    if (pOldArray->count() > 0)    {        CCObject* pObj = NULL;        CCARRAY_FOREACH_REVERSE(pOldArray, pObj)        {            CCAnimationFrame* pElement = (CCAnimationFrame*)pObj;            if (! pElement)            {                break;            }            pNewArray->addObject((CCAnimationFrame*)(pElement->copy()->autorelease()));        }    }    CCAnimation *newAnim = CCAnimation::create(pNewArray, m_pAnimation->getDelayPerUnit(), m_pAnimation->getLoops());    newAnim->setRestoreOriginalFrame(m_pAnimation->getRestoreOriginalFrame());    return create(newAnim);}


 

 

 

0 0