守望者--AIR技术交流

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

搜索
热搜: ANE FlasCC 炼金术
查看: 697|回复: 0

[华丽特效] 模拟液体粒子效果 物理特效

[复制链接]
  • TA的每日心情
    擦汗
    2018-4-10 15:18
  • 签到天数: 447 天

    [LV.9]以坛为家II

    1742

    主题

    2094

    帖子

    13万

    积分

    超级版主

    Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18

    威望
    562
    贡献
    29
    金币
    51691
    钢镚
    1422

    开源英雄守望者

    发表于 2015-7-15 15:52:57 | 显示全部楼层 |阅读模式




    1. package
    2. {
    3.     import flash.display.Bitmap;
    4.     import flash.display.BitmapData;
    5.     import flash.display.Graphics;
    6.     import flash.display.Shape;
    7.     import flash.display.Sprite;
    8.     import flash.events.Event;
    9.     import flash.events.MouseEvent;
    10.     import flash.filters.BlurFilter;
    11.     import flash.geom.ColorTransform;
    12.     import flash.geom.Point;
    13.     import flash.utils.getTimer;
    14.    
    15.     import net.hires.debug.Stats;

    16.     [SW(width="400", height="400", frameRate="24", backgroundColor="0xFFFFFF")]
    17.     public class LiquidTest extends Sprite
    18.     {
    19.         private var particles:Vector.<Particle> = new Vector.<Particle>();
    20.         
    21.         private var gsizeX:int = 100;
    22.         private var gsizeY:int = 100;

    23.         private var grid:Vector.<Vector.<Node>>;
    24.         private var active:Vector.<Node> = new Vector.<Node>();
    25.         private var g:Graphics;
    26.         private var water:Material = new Material(1.0, 1.0, 1.0, 1.0, 1.0, 1.0);
    27.         private var pressed:Boolean;
    28.         private var pressedprev:Boolean;

    29.         private var mx:int;
    30.         private var my:int;
    31.         private var mxprev:int;
    32.         private var myprev:int;

    33.         private var _canvas:BitmapData;
    34.         private var _blur:BlurFilter = new BlurFilter();
    35.         private var _color:ColorTransform = new ColorTransform(1.1, 1.1, 1.1);
    36.         private var _g:Graphics;
    37.         private var _s:Shape;
    38.         private var _o:Point = new Point(0, 0);

    39.         public function LiquidTest()
    40.         {
    41.             addEventListener(Event.ADDED_TO_STAGE, init);
    42.         }

    43.         public function init(event:Event):void
    44.         {
    45.             
    46.             _canvas = new BitmapData(400, 400, false, 0xFFFFFF);
    47.             var _bitmap:Bitmap = addChild(new Bitmap(this._canvas)) as Bitmap;

    48.             _s = new Shape();
    49.             _g = _s.graphics;

    50.             var i:int, j:int;
    51.             grid = new Vector.<Vector.<Node>>(gsizeX, true);
    52.             for (i = 0; i < gsizeX; i++)
    53.             {
    54.                 grid[i] = new Vector.<Node>(gsizeY, true);
    55.                 for (j = 0; j < gsizeY; j++)
    56.                 {
    57.                     grid[i][j] = new Node();
    58.                 }
    59.             }

    60.             stage.addEventListener(Event.ENTER_FRAME, paint);

    61.             stage.addEventListener(MouseEvent.MOUSE_DOWN, mousePressed);
    62.             stage.addEventListener(MouseEvent.MOUSE_UP, mouseReleased);
    63.             stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoved);

    64.             var p:Particle;
    65.             for (i = 0; i < 50; i++)
    66.                 for (j = 0; j < 30; j++)
    67.                 {
    68.                     p = new Particle(water, i + 4, j + 4, 0.0, 0.0);
    69.                     particles.push(p);
    70.                 }
    71.             
    72.             
    73.             addChild(new Stats());
    74.         }

    75.         public function paint(event:Event):void
    76.         {
    77.             _canvas.colorTransform(_canvas.rect, _color);

    78.             simulate();
    79.             _canvas.lock();
    80.             for each (var p:Particle in particles)
    81.             {
    82.                 _canvas.setPixel32(int(4.0 * p.x), int(4.0 * p.y), 0x22000088);
    83.                 _canvas.setPixel32(int(4.0 * (p.x - p.u)), int(4.0 * (p.y - p.v)), 0x440000FF);
    84.             }

    85.             _canvas.draw(_s);
    86.             _canvas.applyFilter(_canvas, _canvas.rect, _o, _blur);
    87.             _canvas.unlock();
    88.         }

    89.         public function mouseMoved(event:MouseEvent):void
    90.         {
    91.             mx = event.localX;
    92.             my = event.localY;
    93.         }

    94.         public function mousePressed(event:MouseEvent):void
    95.         {
    96.             pressed = true;
    97.         }

    98.         public function mouseReleased(event:MouseEvent):void
    99.         {
    100.             pressed = false;
    101.         }

    102.         public function simulate():void
    103.         {
    104.             var drag:Boolean = false;
    105.             var mdx:Number = 0.0, mdy:Number = 0.0;
    106.             if (pressed && pressedprev)
    107.             {
    108.                 drag = true;
    109.                 mdx = 0.25 * (mx - mxprev);
    110.                 mdy = 0.25 * (my - myprev);
    111.             }

    112.             pressedprev = pressed;
    113.             mxprev = mx;
    114.             myprev = my;

    115.             var n:Node, p:Particle;
    116.             for each (n in active)
    117.                 n.clear();
    118.             active.length = 0;

    119.             var i:int, j:int;
    120.             var x:Number, y:Number, phi:Number;
    121.             var fx:Number = 0.0, fy:Number = 0.0;
    122.             for each (p in particles)
    123.             {
    124.                 p.cx = int(p.x - 0.5);
    125.                 p.cy = int(p.y - 0.5);

    126.                 x = p.cx - p.x;
    127.                 p.px[0] = (0.5 * x * x + 1.5 * x + 1.125);
    128.                 p.gx[0] = (x + 1.5);
    129.                 x += 1.0;
    130.                 p.px[1] = (-x * x + 0.75);
    131.                 p.gx[1] = (-2.0 * x);
    132.                 x += 1.0;
    133.                 p.px[2] = (0.5 * x * x - 1.5 * x + 1.125);
    134.                 p.gx[2] = (x - 1.5);

    135.                 y = p.cy - p.y;
    136.                 p.py[0] = (0.5 * y * y + 1.5 * y + 1.125);
    137.                 p.gy[0] = (y + 1.5);
    138.                 y += 1.0;
    139.                 p.py[1] = (-y * y + 0.75);
    140.                 p.gy[1] = (-2.0 * y);
    141.                 y += 1.0;
    142.                 p.py[2] = (0.5 * y * y - 1.5 * y + 1.125);
    143.                 p.gy[2] = (y - 1.5);

    144.                 for (i = 0; i < 3; i++)
    145.                 {
    146.                     for (j = 0; j < 3; j++)
    147.                     {
    148.                         n = grid[p.cx + i][p.cy + j];
    149.                         if (!n.active)
    150.                         {
    151.                             active.push(n);
    152.                             n.active = true;
    153.                         }
    154.                         phi = p.px[i] * p.py[j];
    155.                         n.m += phi * p.mat.m;
    156.                         n.d += phi;
    157.                         n.gx += p.gx[i] * p.py[j];
    158.                         n.gy += p.px[i] * p.gy[j];
    159.                     }
    160.                 }
    161.             }

    162.             var density:Number, pressure:Number, weight:Number;
    163.             var n01:Node, n02:Node;
    164.             var n11:Node, n12:Node;
    165.             var cx:int, cy:int;
    166.             var cxi:int, cyi:int;

    167.             var pdx:Number, pdy:Number;
    168.             var C20:Number, C02:Number, C30:Number, C03:Number;
    169.             var csum1:Number, csum2:Number;
    170.             var C21:Number, C31:Number, C12:Number, C13:Number, C11:Number;

    171.             var u:Number, u2:Number, u3:Number;
    172.             var v:Number, v2:Number, v3:Number;

    173.             for each (p in particles)
    174.             {
    175.                 cx = int(p.x);
    176.                 cy = int(p.y);
    177.                 cxi = cx + 1;
    178.                 cyi = cy + 1;

    179.                 n01 = grid[cx][cy];
    180.                 n02 = grid[cx][cyi];
    181.                 n11 = grid[cxi][cy];
    182.                 n12 = grid[cxi][cyi];

    183.                 pdx = n11.d - n01.d;
    184.                 pdy = n02.d - n01.d;
    185.                 C20 = 3.0 * pdx - n11.gx - 2.0 * n01.gx;
    186.                 C02 = 3.0 * pdy - n02.gy - 2.0 * n01.gy;
    187.                 C30 = -2.0 * pdx + n11.gx + n01.gx;
    188.                 C03 = -2.0 * pdy + n02.gy + n01.gy;
    189.                 csum1 = n01.d + n01.gy + C02 + C03;
    190.                 csum2 = n01.d + n01.gx + C20 + C30;
    191.                 C21 = 3.0 * n12.d - 2.0 * n02.gx - n12.gx - 3.0 * csum1 - C20;
    192.                 C31 = -2.0 * n12.d + n02.gx + n12.gx + 2.0 * csum1 - C30;
    193.                 C12 = 3.0 * n12.d - 2.0 * n11.gy - n12.gy - 3.0 * csum2 - C02;
    194.                 C13 = -2.0 * n12.d + n11.gy + n12.gy + 2.0 * csum2 - C03;
    195.                 C11 = n02.gx - C13 - C12 - n01.gx;

    196.                 u = p.x - cx;
    197.                 u2 = u * u;
    198.                 u3 = u * u2;
    199.                 v = p.y - cy;
    200.                 v2 = v * v;
    201.                 v3 = v * v2;
    202.                 density = n01.d + n01.gx * u + n01.gy * v + C20 * u2 + C02 * v2 + C30 * u3 + C03 * v3 + C21 * u2 * v + C31 * u3 * v + C12 * u * v2 + C13 * u * v3 + C11 * u * v;

    203.                 pressure = density - 1.0;
    204.                 if (pressure > 2.0)
    205.                     pressure = 2.0;

    206.                 fx = 0.0;
    207.                 fy = 0.0;

    208.                 if (p.x < 4.0)
    209.                     fx += p.mat.m * (4.0 - p.x);
    210.                 else if (p.x > gsizeX - 5)
    211.                     fx += p.mat.m * (gsizeX - 5 - p.x);

    212.                 if (p.y < 4.0)
    213.                     fy += p.mat.m * (4.0 - p.y);
    214.                 else if (p.y > gsizeY - 5)
    215.                     fy += p.mat.m * (gsizeY - 5 - p.y);

    216.                 if (drag)
    217.                 {
    218.                     var vx:Number = Math.abs(p.x - 0.25 * mx);
    219.                     var vy:Number = Math.abs(p.y - 0.25 * my);
    220.                     if ((vx < 10.0) && (vy < 10.0))
    221.                     {
    222.                         weight = p.mat.m * (1.0 - vx * 0.10) * (1.0 - vy * 0.10);
    223.                         fx += weight * (mdx - p.u);
    224.                         fy += weight * (mdy - p.v);
    225.                     }
    226.                 }

    227.                 for (i = 0; i < 3; i++)
    228.                 {
    229.                     for (j = 0; j < 3; j++)
    230.                     {
    231.                         n = grid[(p.cx + i)][(p.cy + j)];
    232.                         phi = p.px[i] * p.py[j];
    233.                         n.ax += -((p.gx[i] * p.py[j]) * pressure) + fx * phi;
    234.                         n.ay += -((p.px[i] * p.gy[j]) * pressure) + fy * phi;
    235.                     }
    236.                 }
    237.             }

    238.             for each (n in active)
    239.             {
    240.                 if (n.m > 0.0)
    241.                 {
    242.                     n.ax /= n.m;
    243.                     n.ay /= n.m;
    244.                     n.ay += 0.03;
    245.                 }
    246.             }

    247.             var mu:Number, mv:Number;
    248.             for each (p in particles)
    249.             {
    250.                 for (i = 0; i < 3; i++)
    251.                 {
    252.                     for (j = 0; j < 3; j++)
    253.                     {
    254.                         n = grid[(p.cx + i)][(p.cy + j)];
    255.                         phi = p.px[i] * p.py[j];
    256.                         p.u += phi * n.ax;
    257.                         p.v += phi * n.ay;
    258.                     }
    259.                 }
    260.                 mu = p.mat.m * p.u;
    261.                 mv = p.mat.m * p.v;
    262.                 for (i = 0; i < 3; i++)
    263.                 {
    264.                     for (j = 0; j < 3; j++)
    265.                     {
    266.                         n = grid[(p.cx + i)][(p.cy + j)];
    267.                         phi = p.px[i] * p.py[j];
    268.                         n.u += phi * mu;
    269.                         n.v += phi * mv;
    270.                     }
    271.                 }
    272.             }

    273.             for each (n in active)
    274.             {
    275.                 if (n.m > 0.0)
    276.                 {
    277.                     n.u /= n.m;
    278.                     n.v /= n.m;
    279.                 }
    280.             }

    281.             var gu:Number, gv:Number;
    282.             for each (p in particles)
    283.             {
    284.                 gu = 0.0;
    285.                 gv = 0.0;
    286.                 for (i = 0; i < 3; i++)
    287.                 {
    288.                     for (j = 0; j < 3; j++)
    289.                     {
    290.                         n = grid[(p.cx + i)][(p.cy + j)];
    291.                         phi = p.px[i] * p.py[j];
    292.                         gu += phi * n.u;
    293.                         gv += phi * n.v;
    294.                     }
    295.                 }
    296.                 p.x += gu;
    297.                 p.y += gv;
    298.                 p.u += 1.0 * (gu - p.u);
    299.                 p.v += 1.0 * (gv - p.v);
    300.                 if (p.x < 1.0)
    301.                 {
    302.                     p.x = (1.0 + Math.random() * 0.01);
    303.                     p.u = 0.0;
    304.                 }
    305.                 else if (p.x > gsizeX - 2)
    306.                 {
    307.                     p.x = (gsizeX - 2 - Math.random() * 0.01);
    308.                     p.u = 0.0;
    309.                 }
    310.                 if (p.y < 1.0)
    311.                 {
    312.                     p.y = (1.0 + Math.random() * 0.01);
    313.                     p.v = 0.0;
    314.                 }
    315.                 else if (p.y > gsizeY - 2)
    316.                 {
    317.                     p.y = (gsizeY - 2 - Math.random() * 0.01);
    318.                     p.v = 0.0;
    319.                 }
    320.             }
    321.         }
    322.     }
    323. }

    324. class Node
    325. {
    326.     public var m:Number = 0;
    327.     public var d:Number = 0;
    328.     public var gx:Number = 0;
    329.     public var gy:Number = 0;
    330.     public var u:Number = 0;
    331.     public var v:Number = 0;
    332.     public var ax:Number = 0;
    333.     public var ay:Number = 0;
    334.     public var active:Boolean;
    335.    
    336.     public function clear():void
    337.     {
    338.         m = d = gx = gy = u = v = ax = ay = 0.0;
    339.         active = false;
    340.     }
    341. }

    342. class Particle
    343. {
    344.     public var mat:Material;
    345.     public var x:Number;
    346.     public var y:Number;
    347.     public var u:Number;
    348.     public var v:Number;
    349.     public var dudx:Number = 0;
    350.     public var dudy:Number = 0;
    351.     public var dvdx:Number = 0;
    352.     public var dvdy:Number = 0;
    353.     public var cx:int;
    354.     public var cy:int;
    355.     public var px:Vector.<Number> = new Vector.<Number>(3, true);
    356.     public var py:Vector.<Number> = new Vector.<Number>(3, true);
    357.     public var gx:Vector.<Number> = new Vector.<Number>(3, true);
    358.     public var gy:Vector.<Number> = new Vector.<Number>(3, true);
    359.    
    360.     public function Particle(mat:Material, x:Number, y:Number, u:Number, v:Number)
    361.     {
    362.         this.mat = mat;
    363.         this.x = x;
    364.         this.y = y;
    365.         this.u = u;
    366.         this.v = v;
    367.     }
    368. }

    369. class Material
    370. {
    371.     public var m:Number;
    372.     public var rd:Number;
    373.     public var k:Number;
    374.     public var v:Number;
    375.     public var d:Number;
    376.     public var g:Number;
    377.    
    378.     public function Material(m:Number, rd:Number, k:Number, v:Number, d:Number, g:Number)
    379.     {
    380.         this.m = m;
    381.         this.rd = rd;
    382.         this.k = k;
    383.         this.v = v;
    384.         this.d = d;
    385.         this.g = g;
    386.     }
    387. }
    复制代码





    本文来自:http://wonderfl.net/c/yxe9

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    守望者AIR技术交流社区(www.airmyth.com)
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    
    关闭

    站长推荐上一条 /4 下一条

    QQ|手机版|Archiver|网站地图|小黑屋|守望者 ( 京ICP备14061876号

    GMT+8, 2019-8-19 01:01 , Processed in 0.039448 second(s), 34 queries .

    守望者AIR

    守望者AIR技术交流社区

    本站成立于 2014年12月31日

    快速回复 返回顶部 返回列表