这是一个老外封装的一个自定义动作类,来分析下其实现
头文件:
class Shake : public cocos2d::CCActionInterval {
public:
//构造
Shake();
//创建一个产生震动的持续时间和强度(x轴产生的和y轴产生的变化一样,x = y)
static Shake* create(float d, float strength );
//创建一个产生震动的持续时间和强度(x轴产生的和y轴产生的变化不一样,x != y)
static Shake* createWithStrength(float d, float strengthX, float strengthY );
//初始化动作
bool initWithDuration(float d, float strengthX, float strengthY );
protected:
//设定一个目标
void startWithTarget(cocos2d::CCNode *pTarget);
//刷新,改变目标的x轴和y轴,产生震动效果
void update(float time);
//停止震动
void stop(void);
//目标的原始坐标,用于震动结束后还原目标的坐标
float _initialX, _initialY;
//震动的强度,由目标x轴和y轴控制
float _strengthX, _strengthY;
};
实现:
//初始化参数
Shake::Shake() : _strengthX(0), _strengthY(0), _initialX(0), _initialY(0){
}
Shake* Shake::create(float d, float strength) {
//初始化,x和y都等于strength
return createWithStrength(d, strength, strength);
}
Shake* Shake::createWithStrength(float duration, float strengthX, float strengthY) {
Shake *pRet = new Shake();
if (pRet && pRet->initWithDuration(duration, strengthX, strengthY)) {
pRet->autorelease();
}else {
CC_SAFE_DELETE(pRet);
}
return pRet;
}
bool Shake::initWithDuration(float duration, float strengthX, float strengthY) {
if (CCActionInterval::initWithDuration(duration)) {//初始化父类
//初始化参数
_strengthX = strengthX;
_strengthY = strengthY;
return true;
}
return false;
}
//帮助函数,返回一个包含最大最小值的随机值
static float fgRangeRand(float min, float max) {
float rnd = ((float)rand() / (float)RAND_MAX);
return rnd * (max - min) + min;
}
void Shake::update(float dt) {
//随机产生一个震动范围
float randX = fgRangeRand(-_strengthX, _strengthX) * dt;
float randY = fgRangeRand(-_strengthY, _strengthY) * dt;
//移动目标的坐标,产生震动
m_pTarget->setPosition(ccpAdd(ccp(_initialX, _initialY), ccp(randX, randY)));
}
void Shake::startWithTarget(CCNode *pTarget) {
//绑定目标
CCActionInterval::startWithTarget(pTarget);
//保存目标的出事坐标
_initialX = pTarget->getPosition().x;
_initialY = pTarget->getPosition().y;
}
void Shake::stop(void) {
//动作结束,还原目标的初始位置
this->getTarget()->setPosition(ccp(_initialX, _initialY));
//结束动作
CCActionInterval::stop();
}
接下来,就可以用任何想实现的节点调用runAction即可使用