cocos2d-x 支持按帧通知的帧动画类实现

支持按帧通知的帧动画类实现。

目前的cocos2d-x 2.1.4是不支持帧动画的第n帧播放时通知的功能的,但是也许你需要用,比如第5帧同时播放个音效,怎么办? 参考我封装的类吧。

代码不详细说明,实在是不复杂。

使用说明:

1.A类继承CCAnimateDelegate,并实现completedAnimationFrame方法

2.CDelegateAnimate类对象调用setDelegate(A对象)


CDelegateAnimate.h

//
//  CDelegateAnimate.h
//  Island of Jiang
//
//  Created by apple on 13-7-11.
//
//

#ifndef __Island_of_Jiang__CDelegateAnimate__
#define __Island_of_Jiang__CDelegateAnimate__

#include "CCActionInterval.h"

NS_CC_BEGIN

class CDelegateAnimate;
// 帧通知者基类
class CCAnimateDelegate
{
public:
    virtual void completedAnimationFrame(unsigned int frameId, CDelegateAnimate *pAnimate) = 0;
};

// 自定义帧动画类,支持桢播放通知
class CDelegateAnimate : public CCAnimate {
public:
    CDelegateAnimate();
    ~CDelegateAnimate();
    
    /** creates the action with an Animation and will restore the original frame when the animation is over */
    static CDelegateAnimate* create(CCAnimation *pAnimation);
    virtual void update(float t);
    
    // 注册通知者
    CCAnimateDelegate* getDelegate();
    void setDelegate(CCAnimateDelegate* pDelegate); // retain
    
protected:
    CCAnimateDelegate *m_pAnimateDelegate;
};


NS_CC_END
#endif /* defined(__Island_of_Jiang__CDelegateAnimate__) */

CDelegateAnimate.cpp

//
//  CDelegateAnimate.cpp
//  Island of Jiang
//
//  Created by apple on 13-7-11.
//
//

#include "CDelegateAnimate.h"
#include "CCSprite.h"

NS_CC_BEGIN

CDelegateAnimate::CDelegateAnimate()
: m_pAnimateDelegate(NULL)
{
    
}

CDelegateAnimate::~CDelegateAnimate()
{
    setDelegate(NULL);
}

//
// Animate
//
CDelegateAnimate* CDelegateAnimate::create(CCAnimation *pAnimation)
{
    CDelegateAnimate *pAnimate = new CDelegateAnimate();
    pAnimate->initWithAnimation(pAnimation);
    pAnimate->autorelease();
    
    return pAnimate;
}

void CDelegateAnimate::update(float t)
{    
    CCAnimation* pAnimation = getAnimation();
    // if t==1, ignore. Animation should finish with t==1
    if( t < 1.0f ) {
        t *= pAnimation->getLoops();
        
        // new loop?  If so, reset frame counter
        unsigned int loopNumber = (unsigned int)t;
        if( loopNumber > m_uExecutedLoops ) {
            m_nNextFrame = 0;
            m_uExecutedLoops++;
        }
        
        // new t for animations
        t = fmodf(t, 1.0f);
    }
    
    CCArray* frames = pAnimation->getFrames();
    unsigned int numberOfFrames = frames->count();
    CCSpriteFrame *frameToDisplay = NULL;
    
    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);
            
            // if register
            if (m_pAnimateDelegate) {
                m_pAnimateDelegate->completedAnimationFrame(m_nNextFrame, this);
            }
            m_nNextFrame = i+1;
        }
        // Issue 1438. Could be more than one frame per tick, due to low frame rate or frame delta < 1/FPS
        else {
            break;
        }
    }
}

CCAnimateDelegate* CDelegateAnimate::getDelegate()
{
    return m_pAnimateDelegate;
}

void CDelegateAnimate::setDelegate(CCAnimateDelegate *pDelegate)
{
    CC_SAFE_RELEASE(dynamic_cast<CCObject*>(m_pAnimateDelegate));
    m_pAnimateDelegate = pDelegate;
    CC_SAFE_RETAIN(dynamic_cast<CCObject*>(m_pAnimateDelegate));
}


NS_CC_END


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值