在TestCpp中的EffectsTest示例中展示了一些屏幕特效,它是将屏幕划分为多个格子,并对这些格子进行了动画处理从而产生出相应的屏幕特效
Cocos2d-x提供了屏幕画面上的一些基于网格的动画,首先将要渲染的画面输出到一张纹理上,然后跟据屏幕大小创建相应数量的网格,通过对于网格上的顶点进行改变,形成顶点的运动动画,然后将纹理贴在网格上再绘制出来,就能够出现很多屏幕特效了。
主要是涉及到以下几个文件:
CCGrid.h /cpp :网格数据及渲染,包括基本网格数据和3D网格数据,这是数据的基础。
CCActionGrid.h /cpp :网格基本动画,这是动画的基础。
CCActionGrid3D.h/cpp: 3D网格基本动画,这是3D网格动画的基础。
CCActionTiledGrid.h / cpp :网格衍生动画,这是最终的特效实现。
#ifndef __ACTION_CCGRID_ACTION_H__
#define __ACTION_CCGRID_ACTION_H__
#include "CCActionInterval.h"
#include "CCActionInstant.h"
NS_CC_BEGIN
class CCGridBase;
/** @brief Base class for Grid actions */
class CC_DLL CCGridAction : public CCActionInterval//网格动画基类
{
public:
virtual CCObject* copyWithZone(CCZone* pZone);
virtual void startWithTarget(CCNode *pTarget);
<span style="color:#ff0000;">void CCGridAction::startWithTarget(CCNode *pTarget)
{
//调用时间动画基类的相应函数。
CCActionInterval::startWithTarget(pTarget);
//取得网格数据类。
CCGridBase *newgrid = this->getGrid();
CCNode *t = m_pTarget;
//取得演员的对应网格数据。
CCGridBase *targetGrid = t->getGrid();
//有效性判断,如果演员有网格数据并且已经填充了数据。
if (targetGrid && targetGrid->getReuseGrid() > 0)
{
//如果网格数据被激活并且其格子大小与本类实例的网格大小相同。
if (targetGrid->isActive() && targetGrid->getGridSize().x == m_sGridSize.x
&& targetGrid->getGridSize().y == m_sGridSize.y /*&& dynamic_cast<CCGridBase*>(targetGrid) != NULL*/)
{
//演员的网格数据恢复为原始数据。
targetGrid->reuse();
}
else
{
CCAssert(0, "");
}
}
else
{
//如果演员没有创建网格数据或者网格数据已经恢复为原始顶点。
//如果演员的网格数据有效并且是激活状态。
if (targetGrid && targetGrid->isActive())
{
//将其设为未激活。
targetGrid->setActive(false);
}
//将当前类实例的网格数据设置给演员之后激活。
t->setGrid(newgrid);
t->getGrid()->setActive(true);
}
}</span>
virtual CCActionInterval* reverse(void);
/** initializes the action with size and duration */
//初始化网格的大小和动画的时长。
virtual bool initWithDuration(float duration, const CCSize& gridSize);
/** returns the grid */
//返回网格
virtual CCGridBase* getGrid(void);
public:
/** creates the action with size and duration */
//创建网格动画 1、格子大小 2、动画时长
static CCGridAction* create(float duration, const CCSize& gridSize);
protected:
CCSize m_sGridSize;//格子大小。
};
/**
@brief Base class for CCGrid3D actions.
Grid3D actions can modify a non-tiled grid.
*/
class CC_DLL CCGrid3DAction : public CCGridAction //3D网格动画基类
{
public:
//取得网格
virtual CCGridBase* getGrid(void);
//返回对应网格位置的顶点。
ccVertex3F vertex(const CCPoint& position);
//返回对应网格位置的原始顶点。
ccVertex3F originalVertex(const CCPoint& position);
//设置对应网格位置的顶点。
void setVertex(const CCPoint& position, const ccVertex3F& vertex);
public:
//创建3d网格
static CCGrid3DAction* create(float duration, const CCSize& gridSize);
};
/** @brief Base class for CCTiledGrid3D actions */
class CC_DLL CCTiledGrid3DAction : public CCGridAction//派生于CCGridAction的3D格子动画类。
{
public:
//返回对应位置的格子顶点数据。
ccQuad3 tile(const CCPoint& position);
//返回对应位置的原始格子顶点数据。
ccQuad3 originalTile(const CCPoint& position);
//设置对应位置的格子数据。
void setTile(const CCPoint& position, const ccQuad3& coords);
//返回网格数据。
virtual CCGridBase* getGrid(void);
public:
//创建瓦片3d网格动画
static CCTiledGrid3DAction* create(float duration, const CCSize& gridSize);
};
/** @brief CCAccelDeccelAmplitude action */
class CC_DLL CCAccelDeccelAmplitude : public CCActionInterval
//Amplitude 振幅 网格所用的变速动画基类:先加速再减速。
//要求被修饰action 有amplitude属性 只有继承自上面3个网格动作的动作才会有这个属性 所以可以说是网格所用
{
public:
virtual ~CCAccelDeccelAmplitude(void);
/** initializes the action with an inner action that has the amplitude property, and a duration time */
//初始化 1、被修饰动作 2、时间
bool initWithAction(CCAction *pAction, float duration);
virtual void startWithTarget(CCNode *pTarget);
virtual void update(float time);
<span style="color:#ff0000;">void CCAccelDeccelAmplitude::update(float time)
{
//创建一个f值变为进度的2倍。
float f = time * 2;
//如果动画时间大于一半,让进度由1再变为0。
if (f > 1)
{
f -= 1;
f = 1 - f;
}
//使用powf处理来形成一个变速曲线公式来达到变速目的。
((CCAccelDeccelAmplitude*)(m_pOther))->setAmplitudeRate(powf(f, m_fRate));
}</span>
virtual CCActionInterval* reverse(void);
/** get amplitude rate */
//取得变化率
inline float getRate(void) { return m_fRate; }
/** set amplitude rate */
inline void setRate(float fRate) { m_fRate = fRate; }
public:
/** creates the action with an inner action that has the amplitude property, and a duration time */
//创建CCAccelDeccelAmplitude动作
static CCAccelDeccelAmplitude* create(CCAction *pAction, float duration);
protected:
float m_fRate;
CCActionInterval *m_pOther;
};
/** @brief CCAccelAmplitude action */
class CC_DLL CCAccelAmplitude : public CCActionInterval
//网格所用的变速动画基类:加速动画
{
public:
~CCAccelAmplitude(void);
//初始化
bool initWithAction(CCAction *pAction, float duration);
//得到 设置速率
inline float getRate(void) { return m_fRate; }
inline void setRate(float fRate) { m_fRate = fRate; }
virtual void startWithTarget(CCNode *pTarget);
virtual void update(float time);
<span style="color:#ff0000;">//动画更新处理。
void CCAccelAmplitude::update(float time)
{
//创建变速曲线来设置控制动画的速率。
((CCAccelAmplitude*)(m_pOther))->setAmplitudeRate(powf(time, m_fRate));
//更新控制动画。
m_pOther->update(time);
}</span>
virtual CCActionInterval* reverse(void);
public:
//创建
static CCAccelAmplitude* create(CCAction *pAction, float duration);
protected:
float m_fRate;
CCActionInterval *m_pOther;
};
/** @brief CCDeccelAmplitude action */
class CC_DLL CCDeccelAmplitude : public CCActionInterval
//网格所用的变速动画基类:减速动画。
{
public:
~CCDeccelAmplitude(void);
/** initializes the action with an inner action that has the amplitude property, and a duration time */
bool initWithAction(CCAction *pAction, float duration);
/** get amplitude rate */
inline float getRate(void) { return m_fRate; }
/** set amplitude rate */
inline void setRate(float fRate) { m_fRate = fRate; }
virtual void startWithTarget(CCNode *pTarget);
virtual void update(float time);
virtual CCActionInterval* reverse(void);
public:
/** creates the action with an inner action that has the amplitude property, and a duration time */
static CCDeccelAmplitude* create(CCAction *pAction, float duration);
protected:
float m_fRate;
CCActionInterval *m_pOther;
};
/** @brief CCStopGrid action.
@warning Don't call this action if another grid action is active.
Call if you want to remove the the grid effect. Example:
CCSequence::actions(Lens::action(...), CCStopGrid::action(...), NULL);
*/
class CC_DLL CCStopGrid : public CCActionInstant//停止网格动画。
{
public:
virtual void startWithTarget(CCNode *pTarget);
<span style="color:#ff0000;">//设置演示当前动画的演员。
void CCStopGrid::startWithTarget(CCNode *pTarget)
{
//调用基类的相应函数。
CCActionInstant::startWithTarget(pTarget);
//取得演员所用的网格数据。
CCGridBase *pGrid = m_pTarget->getGrid();
if (pGrid && pGrid->isActive())
{
//如果是激活状态,取消激活。
pGrid->setActive(false);
}
}</span>
public:
/** Allocates and initializes the action */
static CCStopGrid* create(void);
};
/** @brief CCReuseGrid action */
class CC_DLL CCReuseGrid : public CCActionInstant//恢复网格动画。
{
public:
/** initializes an action with the number of times that the current grid will be reused */
bool initWithTimes(int times);
virtual void startWithTarget(CCNode *pTarget);
public:
/** creates an action with the number of times that the current grid will be reused */
static CCReuseGrid* create(int times);
protected:
int m_nTimes;
};
NS_CC_END
#endif // __ACTION_CCGRID_ACTION_H__