支持按帧通知的帧动画类实现。
目前的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