cocos2d-x 3.0抖动效果

转自:http://blog.sina.com.cn/s/blog_7cbd10170102uxi1.html


最近使用cocos2dx需要用到一个需求,就是关于图片精灵抖动的动作效果。稍微查了一下,找到一个CCShake用来实现这样效果的。不过网上几乎都是在2.x平台上的。所以我根据需求把它改成能用在3.x平台上的。下面放一下代码先:

//
//  CCShake.h
//
//  Code by Francois Guibert
//  Contact: www.frozax.com - http://twitter.com/frozax - www.facebook.com/frozax
//
//  何遵祖修改于2014.7.10 支持cocos2dx 3.0 修正了动作执行精灵位置错误问题 测试环境:cocos2d-x-3.0rc1

#ifndef __war__CCShake__
#define __war__CCShake__

#include
#include "cocos2d.h"

using namespace cocos2d;

class Shake : public ActionInterval
{
public:
    Shake();
    
    // Create the action with a time and a strength (same in x and y)
    // 产生震动效果的初始化函数参数,两个方向相同
    // @param d 震动持续的时间
    // @param strength 震动的幅度
    static Shake* create(float d,float strength);
    // Create the action with a time and strengths (different in x and y)
    // 产生震动效果的初始化函数,两个方向值不一样
    static Shake* create(float d,float strength_x,float strength_y);
    bool initWithDuration(float d,float strength_y);
    
    //以下都是重写父类抽象类的函数(必须重写)
    virtual Shake* clone() const override;
    virtual Shake* reverse(void) const override;
    virtual void startWithTarget(Node *target) override;
    virtual void update(float time) override;
    virtual void stop(void);
    
protected:
     // Initial position of the shaked node
     // 精灵的位置
     float _initial_x,_initial_y;
     // Strength of the action
     // 抖动的幅度
     float _strength_x,_strength_y;
};

//
//  Shake.cpp
//  war
//

#include "CCShake.h"

// not really useful,but I like clean default constructors
Shake::Shake() : _strength_x(0),_strength_y(0),_initial_x(0),_initial_y(0)
{
}

Shake* Shake::create(float d,float strength )
{
    // call other construction method with twice the same strength
    return create( d,strength,strength );
}

Shake* Shake::create(float duration,float strength_y)
{
    Shake *p_action = new Shake();
    p_action->initWithDuration(duration,strength_x,strength_y);
    p_action->autorelease();
    
    return p_action;
}

bool Shake::initWithDuration(float duration,float strength_y)
{
    if (CCActionInterval::initWithDuration(duration))
    {
        _strength_x = strength_x;
        _strength_y = strength_y;
        
        return true;
    }
    
    return false;
}

// Helper function. I included it here so that you can compile the whole file
// it returns a random value between min and max included
float fgRangeRand( float min,float max )
{
     float rnd = ((float)rand()/(float)RAND_MAX);
     return rnd*(max-min)+min;
}

void Shake::update(float time)
{
     float randx = fgRangeRand( -_strength_x,_strength_x );
     float randy = fgRangeRand( -_strength_y,_strength_y );
    
     // move the target to a shaked position
     _target->setPosition(Vec2(_initial_x + randx,_initial_y + randy));
}

Shake* Shake::clone(void) const
{
    auto a = new Shake();
    a->initWithDuration(_duration,_strength_x,_strength_y);
    a->autorelease();
    return a;
}

Shake* Shake::reverse() const
{
    return Shake::create(_duration,-_strength_x,-_strength_y);
}

void Shake::startWithTarget(Node *target)
{
    CCActionInterval::startWithTarget(target);
    
    // save the initial position
    _initial_x = target->getPosition().x;
    _initial_y = target->getPosition().y;
}

void Shake::stop(void)
{
    // Action is done,reset clip position
    _target->setPosition(Vec2( _initial_x,_initial_y ) );
    
    CCActionInterval::stop();
}

Cocos2dx3.0中对ActionInterval类中的抽象类方法增加多了两个,一个是clone(),一个是reverse()。前者作用是起到一个复制的作用,后者是反向,让动作以当初设定的相反方向执行。

这个Shake主要的核心是在update和fgRangeRand方法中,主要思路是在fgRangeRand中在类的_strength(-_strength ~_strength)值的范围里面产生随机数,然后根据精灵位置加上这里产生的值,从而不断的快速改变位置来参数抖动的效果。


在使用过程中,由于某处设置错误,导致shake动作被调用两次,完成动作后精灵偏离了原来的位置。所以,切记,不能被同时执行两个shake动作。

相关文章

    本文实践自 RayWenderlich、Ali Hafizji 的文章《...
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@1...
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从C...
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发...
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《...
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试...