关于模仿流体的一点构思

来个果冻

jdfw.gif
]( http://upload-images.jianshu.io/upload_images/1744941-78b07f08d22f9a57.gif?imageMogr2/auto-orient/strip)
至于调用,只要放一张
关于模仿流体的一点构思_第1张图片
6.png

这样的小圆图,创建一个精灵-用

auto ac1 = CCLiquid::create(1, CCSizeMake(12,12), 3, 22);
pSprite->runAction(ac1);

看起来是不是有点像果冻,或者说点击果冻的时候
这个流体的术是什么,在我们点击的时候到底对这张图片做了什么操作
CCliquid这个函数的创建放在CCActionGrid3D这里,liquid的创建传入了四个参数
执行时间、切割细致程度,弹动次数,弹动幅度

void CCLiquid::update(float time)
{
    int i, j;
    for (i = 1; i < m_sGridSize.width; ++i)
    {
        for (j = 1; j < m_sGridSize.height; ++j)
        {
            ccVertex3F v = originalVertex(ccp(i, j));
            v.x = (v.x + (sinf(time * (float)M_PI * m_nWaves * 2 + v.x * (1.0f - pow(time,4))*0.01) * m_fAmplitude * m_fAmplitudeRate));
            v.y = (v.y + (sinf(time * (float)M_PI * m_nWaves * 2 + v.y * (1.0f - pow(time,4))*0.01) * m_fAmplitude * m_fAmplitudeRate));
            setVertex(ccp(i, j), v);
        }
    }
}

这里你和cocos2d该文件下的原函数做对比可能也发现了

//原函数
v.x = (v.x + (sinf(time * (float)M_PI * _waves * 2 + v.x * .01f) * _amplitude * _amplitudeRate));
//不变原效果的小改造
v.x = (v.x + (sinf(time * (float)M_PI * m_nWaves * 2 + v.x * (1.0f - pow(time,4))*0.01) * m_fAmplitude * m_fAmplitudeRate));
关于模仿流体的一点构思_第2张图片
yuan.png

这里多了一个 (1.0f - pow(time,4)) 这是因为原函数将一个图形的顶点进行拉伸后,到时间结束,状态并没有将它复原,动作完成这时候time=1.0f 带入原函数
v.x = v.x + sin(v.x0.01) 到结束的时候X轴还是多出了sin(0.01v.x)
因此我所加的 (1.0f - pow(time,4)) 作用便是在结束的时候把动画拉回来,同期修复的还有ccwave3d,CCRipple3D ,CCshake3d,CCwaves 好吧这算一个方法,当然,仅仅修改原本存在的小bug这算什么事,那我多唠两句吧!

用wave3d试试

我们让水波动起来


bowen.gif
 D.imgp("illustrated/bg.png", 0, 0):anchor(ccp(0, 0)):to(self)
-- 水波纹1
    local ripple1 = D.imgp("illustrated/ripple.png", 0, 0):anchor(ccp(0, 0)):to(self)
    local waves3D = CCLiquid:create(8, CCSize(10, 10), 4, 10)
    local RepeatForever = CCRepeatForever:create(waves3D)
    ripple1:runAction(RepeatForever)

简单的Shader模仿

jdfw.gif

好吧,敢用Shader的前提是你所用的框架处理shader的垃圾回收处理做的不错,不会因为开一小会就卡的不行,这里我直接放源码,原理就是像素点的偏移

#ifdef GL_ES
    precision mediump float;
#endif
//固定模式传入长宽,resolution即分辨率 CC_Texture0为自身像素 PosX,PosY为鼠标位置
//v_texCoord 图片全屏时候等于 vec2( gl_FragCoord.x/width, (1.-gl_FragCoord.y/height) ); 

uniform float width;
uniform float height;
uniform float PosX; 
uniform float PosY; 

#define resolution vec2(width,height)
uniform sampler2D CC_Texture0;
varying vec2 v_texCoord;
varying vec4 v_fragmentColor;
//uniform float time;
#define time CC_Time.x

const float PI = 3.1415926535897932;  
const float speed = 0.2;  
const float speed_x = 0.3;  
const float speed_y = 0.3;  
 
const float intensity = 3.0;  
const int steps = 8;  
const float frequency = 4.0;  
const int angle = 7; 
 
const float delta = 20.0;  
const float intence = 400.0;  
const float emboss = 0.3;  


float col(vec2 coord)  
{  
    float delta_theta = 2.0 * PI / float(angle);  
    float col = 0.0;  
    float theta = 0.0;  
    for (int i = 0; i < steps; i++)  
    {
        vec2 adjc = coord;
        theta = delta_theta * float(i);
        adjc.x += cos(theta)*time*speed + time * speed_x;  
        adjc.y -= sin(theta)*time*speed - time * speed_y;  
        col = col + cos((adjc.x*cos(theta) - adjc.y*sin(theta))*frequency)*intensity;  
    }
    return cos(col);
} 
void main()
{

    vec2 p = (gl_FragCoord.xy) / resolution.xy, c1 = p, c2 = p;  
    float cc1 = col(c1);  
 
    c2.x += resolution.x/delta;  
    float dx = emboss*(cc1-col(c2))/delta;  
 
    c2.x = p.x;  
    c2.y += resolution.y/delta;  
    float dy = emboss*(cc1-col(c2))/delta;  
 
    c1.x += dx;  
    c1.y += dy;  
    float alpha = 1.+dot(dx,dy)*intence;  
    gl_FragColor = v_fragmentColor*texture2D(CC_Texture0,vec2(c1.x,1.-c1.y))*(alpha*alpha);//*(alpha) *v_color*(alpha);  
}                                                                                       

等等...发生了什么情况,我刚插了一张gif结果前面写的东西不见了...这是有长度限制?那就先到这里吧!--ByBBChangwei-16-04-04

你可能感兴趣的:(关于模仿流体的一点构思)