3D相关的动画都是继承Grid3DAction
本质上是用GirdBase进行创建动画的小块。
Shaky3D
晃动特效
// 持续时间(时间过后不会回到原来的样子)
// 整个屏幕被分成几行几列
// 晃动的范围
// z轴是否晃动
static Shaky3D* create(float initWithDuration, const Size& gridSize, int range, bool shakeZ);
关键实现
void Shaky3D::update(float /*time*/)
{
int i, j;
for (i = 0; i < (_gridSize.width+1); ++i)
{
for (j = 0; j < (_gridSize.height+1); ++j)
{
Vec3 v = getOriginalVertex(Vec2(i ,j));
v.x += (rand() % (_randrange*2)) - _randrange;
v.y += (rand() % (_randrange*2)) - _randrange;
if (_shakeZ)
{
v.z += (rand() % (_randrange*2)) - _randrange;
}
setVertex(Vec2(i, j), v);
}
}
}
示例代码
cc.Shaky3D:create(5, cc.size(15,10), 5, false)
Waves3D
波浪特效
// 持续时间(时间过后不会回到原来的样子)
// 整个屏幕被分成几行几列
// 波动的速率
// 振幅
static Waves3D* create(float duration, const Size& gridSize, unsigned int waves, float amplitude);
源码
void Waves3D::update(float time)
{
int i, j;
for (i = 0; i < _gridSize.width + 1; ++i)
{
for (j = 0; j < _gridSize.height + 1; ++j)
{
Vec3 v = getOriginalVertex(Vec2(i ,j));
v.z += (sinf((float)M_PI * time * _waves * 2 + (v.y+v.x) * 0.01f) * _amplitude * _amplitudeRate);
//CCLOG("v.z offset is %f\n", (sinf((float)M_PI * time * _waves * 2 + (v.y+v.x) * .01f) * _amplitude * _amplitudeRate));
setVertex(Vec2(i, j), v);
}
}
}
示例
cc.Waves3D:create(5, cc.size(15,10), 5, 40)
FlipX3D
X轴翻转动画
// 反转时间
static FlipX3D* create(float duration);
源码
void FlipX3D::update(float time)
{
float angle = (float)M_PI * time; // 180 degrees
float mz = sinf(angle);
angle = angle / 2.0f; // x calculates degrees from 0 to 90
float mx = cosf(angle);
Vec3 v0, v1, v, diff;
v0 = getOriginalVertex(Vec2(1.0f, 1.0f));
v1 = getOriginalVertex(Vec2());
float x0 = v0.x;
float x1 = v1.x;
float x;
Vec2 a, b, c, d;
if ( x0 > x1 )
{
// Normal Grid
a.setZero();
b.set(0.0f, 1.0f);
c.set(1.0f, 0.0f);
d.set(1.0f, 1.0f);
x = x0;
}
else
{
// Reversed Grid
c.setZero();
d.set(0.0f, 1.0f);
a.set(1.0f, 0.0f);
b.set(1.0f, 1.0f);
x = x1;
}
diff.x = ( x - x * mx );
diff.z = fabsf( floorf( (x * mz) / 4.0f ) );
// bottom-left
v = getOriginalVertex(a);
v.x = diff.x;
v.z += diff.z;
setVertex(a, v);
// upper-left
v = getOriginalVertex(b);
v.x = diff.x;
v.z += diff.z;
setVertex(b, v);
// bottom-right
v = getOriginalVertex(c);
v.x -= diff.x;
v.z -= diff.z;
setVertex(c, v);
// upper-right
v = getOriginalVertex(d);
v.x -= diff.x;
v.z -= diff.z;
setVertex(d, v);
}
示例
cc.FlipX3D:create(3)
FlipY3D
Y轴翻转动画
// 时间
static FlipY3D* create(float duration);
源码
void FlipY3D::update(float time)
{
float angle = (float)M_PI * time; // 180 degrees
float mz = sinf( angle );
angle = angle / 2.0f; // x calculates degrees from 0 to 90
float my = cosf(angle);
Vec3 v0, v1, v, diff;
v0 = getOriginalVertex(Vec2(1.0f, 1.0f));
v1 = getOriginalVertex(Vec2());
float y0 = v0.y;
float y1 = v1.y;
float y;
Vec2 a, b, c, d;
if (y0 > y1)
{
// Normal Grid
a.setZero();
b.set(0.0f, 1.0f);
c.set(1.0f, 0.0f);
d.set(1.0f, 1.0f);
y = y0;
}
else
{
// Reversed Grid
b.setZero();
a.set(0.0f, 1.0f);
d.set(1.0f, 0.0f);
c.set(1.0f, 1.0f);
y = y1;
}
diff.y = y - y * my;
diff.z = fabsf(floorf((y * mz) / 4.0f));
// bottom-left
v = getOriginalVertex(a);
v.y = diff.y;
v.z += diff.z;
setVertex(a, v);
// upper-left
v = getOriginalVertex(b);
v.y -= diff.y;
v.z -= diff.z;
setVertex(b, v);
// bottom-right
v = getOriginalVertex(c);
v.y = diff.y;
v.z += diff.z;
setVertex(c, v);
// upper-right
v = getOriginalVertex(d);
v.y -= diff.y;
v.z -= diff.z;
setVertex(d, v);
}
示例
cc.FlipY3D:create(3)
Lens3D
凸镜特效
// 持续时间(时间过后不会回到原来的样子)
// 网格大小
// 凸镜中心点
// 半径
static Lens3D* create(float duration, const Size& gridSize, const Vec2& position, float radius);
源码
void Lens3D::update(float /*time*/)
{
if (_dirty)
{
int i, j;
for (i = 0; i < _gridSize.width + 1; ++i)
{
for (j = 0; j < _gridSize.height + 1; ++j)
{
Vec3 v = getOriginalVertex(Vec2(i, j));
Vec2 vect = _position - Vec2(v.x, v.y);
float r = vect.getLength();
if (r < _radius)
{
r = _radius - r;
float pre_log = r / _radius;
if ( pre_log == 0 )
{
pre_log = 0.001f;
}
float l = logf(pre_log) * _lensEffect;
float new_r = expf( l ) * _radius;
if (vect.getLength() > 0)
{
vect.normalize();
Vec2 new_vect = vect * new_r;
v.z += (_concave ? -1.0f : 1.0f) * new_vect.getLength() * _lensEffect;
}
}
setVertex(Vec2(i, j), v);
}
}
_dirty = false;
}
}
示例
cc.Lens3D:create(2, cc.size(15,10), cc.p(size.width/2,size.height/2), 240)
Ripple3D
水波特效
// 持续时间(时间过后不会回到原来的样子)
// 网格大小
// 凸镜中心点
// 半径
// 波动的速率
// 振幅
static Ripple3D* create(float duration, const Size& gridSize, const Vec2& position, float radius, unsigned int waves, float amplitude);
源码
void Ripple3D::update(float time)
{
int i, j;
for (i = 0; i < (_gridSize.width+1); ++i)
{
for (j = 0; j < (_gridSize.height+1); ++j)
{
Vec3 v = getOriginalVertex(Vec2(i, j));
Vec2 vect = _position - Vec2(v.x,v.y);
float r = vect.getLength();
if (r < _radius)
{
r = _radius - r;
float rate = powf(r / _radius, 2);
v.z += (sinf( time*(float)M_PI * _waves * 2 + r * 0.1f) * _amplitude * _amplitudeRate * rate);
}
setVertex(Vec2(i, j), v);
}
}
}
示例
// 持续时间(时间过后不会回到原来的样子)
// 整个屏幕被分成几行几列
// 波动的速率
// 振幅
cc.Ripple3D:create(t, cc.size(32,24), cc.p(size.width/2,size.height/2), 240, 4, 160)
Liquid
液体特效
// 持续时间(时间过后不会回到原来的样子)
// 整个屏幕被分成几行几列
// 波动的速率
// 振幅
static Liquid* create(float duration, const Size& gridSize, unsigned int waves, float amplitude);
源码
void Liquid::update(float time)
{
int i, j;
for (i = 1; i < _gridSize.width; ++i)
{
for (j = 1; j < _gridSize.height; ++j)
{
Vec3 v = getOriginalVertex(Vec2(i, j));
v.x = (v.x + (sinf(time * (float)M_PI * _waves * 2 + v.x * .01f) * _amplitude * _amplitudeRate));
v.y = (v.y + (sinf(time * (float)M_PI * _waves * 2 + v.y * .01f) * _amplitude * _amplitudeRate));
setVertex(Vec2(i, j), v);
}
}
}
示例
cc.Liquid:create(3, cc.size(16,12), 4, 20)
Waves
带方向的波浪特效,水平与垂直
// 持续时间(时间过后不会回到原来的样子)
// 整个屏幕被分成几行几列
// 波动的速率
// 振幅
// 是否是水平方向
// 是否是垂直方向
static Waves* create(float duration, const Size& gridSize, unsigned int waves, float amplitude, bool horizontal, bool vertical);
源码
void Waves::update(float time)
{
int i, j;
for (i = 0; i < _gridSize.width + 1; ++i)
{
for (j = 0; j < _gridSize.height + 1; ++j)
{
Vec3 v = getOriginalVertex(Vec2(i, j));
if (_vertical)
{
v.x = (v.x + (sinf(time * (float)M_PI * _waves * 2 + v.y * .01f) * _amplitude * _amplitudeRate));
}
if (_horizontal)
{
v.y = (v.y + (sinf(time * (float)M_PI * _waves * 2 + v.x * .01f) * _amplitude * _amplitudeRate));
}
setVertex(Vec2(i, j), v);
}
}
}
例子
cc.Waves:create(2, cc.size(16,12), 4, 20, true, true)