※現在、「wonderfl build flash online」求人コンテンツ制作に関してのアンケートを実施中です!みなさまのお力添えを頂いて、続々とアンケート結果が集まっていますが、まだまだ募集しております。ご協力のほど、どうぞよろしくお願いいたします!

wonderfl運営事務局
→アンケートページ(※ログインしてからお答えいただけるようになっています。)

 notice: Flash editor updated! Join the development! Thanks to MiniBuilder


TALK
きもちい 水さわってるみたいだねー
at 2009/10/23 18:31:08 by
FAVORITE BY
:
流体,例子流体,例子
:
:
速度线
:
particle流体シミュレーション
:
きもちいいいいい
:
:
:
BitmapDataparticlesマウスドラッグでパーティクルが流れる
:
:
:
:
:
:
:
:
:
かっこよすぎ
:
流体
:
:
サラサラ流れるイメージ
:
:
粒子流体
:
46x46のグリッドぐらいでもナチュラルな動き。粒子の描画方法でいろいろ応用できそう。
:
particleすげ
FORKED
  1. // forked from miniapp's 流体パーティクル
  2. /**
  3.  * Fluid \ Learning \ Processing 1.0
  4.  * http://www.processing.org/learning/topics/fluid.html
  5.  * 
  6.  * via [Flash]流体っぽいのを作ろうと思った | blog ViolentCoding
  7.  * http://violentcoding.com/blog/2008/07/26/archives/135
  8.  */
  9. package {
  10.     import flash.display.Bitmap;
  11.     import flash.display.BitmapData;
  12.     import flash.display.Sprite;
  13.     import flash.display.StageAlign;
  14.     import flash.display.StageQuality;
  15.     import flash.display.StageScaleMode;
  16.     import flash.events.Event;
  17.     import flash.events.MouseEvent;
  18.     import flash.geom.ColorTransform;
  19.     import flash.geom.Rectangle;
  20.     import net.hires.debug.Stats;
  21.     
  22.     [SWF(backgroundColor=0x0, width=465, height=465, frameRate=60)]
  23.     public class FluidLine extends Sprite {
  24.         
  25.         public function FluidLine() {
  26.             if (stage) init();
  27.             else addEventListener(Event.ADDED_TO_STAGE, init);
  28.         }
  29.         
  30.         private var pmouseX:Number;
  31.         private var pmouseY:Number;
  32.         private var canvasWidth:int = 465;
  33.         private var canvasHeight:int = 465;
  34.         private var mousePressed:Boolean;
  35.         private var resolution:int = 10;
  36.         private var penSize:int = 40;
  37.         private var numCols:int = canvasWidth / resolution;;
  38.         private var numRows:int = canvasHeight / resolution;
  39.         private var numParticles:int = 6000;
  40.         private var gridDatasVectors:Vector.<Vector.<GridData>> = new Vector.<Vector.<GridData>>();
  41.         private var particles:Vector.<Particle> = new Vector.<Particle>(numParticles, true);
  42.         private var pcount:int = 0;
  43.         
  44.         private function init(e:Event = null):void {
  45.             removeEventListener(Event.ADDED_TO_STAGE, init);
  46.             stage.scaleMode = StageScaleMode.NO_SCALE;
  47.             stage.align = StageAlign.TOP_LEFT;
  48.             
  49.             stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
  50.             stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
  51.             
  52. Wonderfl.capture_delay(5);
  53.             //stage.quality = StageQuality.MEDIUM;
  54.             //addChild(new Stats());
  55.             
  56.             for (var i:int = 0; i < numParticles; i++) {
  57.                 particles[i] = new Particle(Math.random() * canvasWidth, Math.random() * canvasHeight);
  58.             }
  59.             
  60.             for (var col:int = 0; col < numCols; ++col) { 
  61.                 gridDatasVectors[col] = new Vector.<GridData>(numRows, true);
  62.                 for (var row:int = 0; row < numRows; ++row) { 
  63.                     var gridData:GridData = new GridData(col * resolution, row * resolution, resolution);
  64.                     gridData.col = col;
  65.                     gridData.row = row;
  66.                     gridDatasVectors[col][row] = gridData;
  67.                 }
  68.             }
  69.             
  70.             //隣接するグリッドをセットしていく。
  71.             for (col = 0; col < numCols; ++col) { 
  72.                 for (row = 0; row < numRows; ++row) { 
  73.                     gridData = gridDatasVectors[col][row];
  74.                     if (row > 0) {
  75.                         var up:GridData = gridDatasVectors[col][row - 1];//上
  76.                         gridData.up = up;
  77.                         up.low = gridData;//下
  78.                     }
  79.                     
  80.                     if (col > 0) {
  81.                         var left:GridData = gridDatasVectors[col - 1][row];//左
  82.                         gridData.left = left;
  83.                         left.right = gridData;//右
  84.                     }
  85.                     
  86.                     if (row > 0 && col > 0) {
  87.                         var upperLeft:GridData = gridDatasVectors[col - 1][row - 1];
  88.                         gridData.upperLeft = upperLeft;
  89.                         upperLeft.lowerRight = gridData;
  90.                     }
  91.                     
  92.                     if (row > 0 && col < numCols - 1) {
  93.                         var upperRight:GridData = gridDatasVectors[col + 1][row - 1];
  94.                         gridData.upperRight = upperRight;
  95.                         upperRight.lowerLeft = gridData;
  96.                     }
  97.                 }
  98.             }
  99.             
  100.             gridDatasVectors.fixed = true;
  101.             addEventListener(Event.ENTER_FRAME, draw);
  102.         }
  103.         
  104.         private function draw(e:Event):void {
  105.             var mouseXvel:Number = mouseX - pmouseX;
  106.             var mouseYvel:Number = mouseY - pmouseY;
  107.             
  108.             for each(var gridDatas:Vector.<GridData> in gridDatasVectors) {
  109.                 for each(var gridData:GridData in gridDatas) {
  110.                     if (mousePressed) {
  111.                         updateGridDataVelocity(gridData, mouseXvel, mouseYvel, penSize);
  112.                     }
  113.                     updatePressure(gridData);
  114.                     
  115.                 }
  116.             }
  117.             
  118.             graphics.clear();
  119.             graphics.lineStyle(1, 0xFFFFFF);
  120.             updateParticle();
  121.             
  122.             for each(gridDatas in gridDatasVectors) {
  123.                 for each(gridData in gridDatas) {
  124.                     apdateVelocity(gridData);
  125.                 }
  126.             }
  127.             
  128.             pmouseX = mouseX;
  129.             pmouseY = mouseY;
  130.         }
  131.         
  132.         public function updateParticle():void {
  133.             for each(var p:Particle in particles) {
  134.                 if (p.x >= 0 && p.x < canvasWidth && p.y >= 0 && p.y < canvasHeight) {
  135.                     var col:int = int(p.x / resolution);//自身が属しているgridDataを見つける
  136.                     var row:int = int(p.y / resolution);
  137.                     
  138.                     if (col > numCols - 1) col = numCols - 1;
  139.                     if (row > numRows - 1) row = numRows - 1;
  140.                     
  141.                     var gridData:GridData = gridDatasVectors[col][row];
  142.                     
  143.                     var ax:Number = (p.x % resolution) / resolution;
  144.                     var ay:Number = (p.y % resolution) / resolution;
  145.                     p.xvel += (1 - ax) * gridData.xvel * 0.05;
  146.                     p.yvel += (1 - ay) * gridData.yvel * 0.05;
  147.                     
  148.                     p.xvel += ax * gridData.right.xvel * 0.05;
  149.                     p.yvel += ax * gridData.right.yvel * 0.05;
  150.                     
  151.                     p.xvel += ay * gridData.low.xvel * 0.05;
  152.                     p.yvel += ay * gridData.low.yvel * 0.05;
  153.                     
  154.                     p.x += p.xvel;
  155.                     p.y += p.yvel;
  156.                     
  157.                     var dx:Number = p.px - p.x;
  158.                     var dy:Number = p.py - p.y;
  159.                     var dist:Number = Math.sqrt(dx * dx + dy * dy);
  160.                     var limit:Number = Math.random() * 0.5;
  161.                     
  162.                     if (dist > limit) {
  163.                         graphics.moveTo(p.x, p.y);
  164.                         graphics.lineTo(p.px, p.py);
  165.                     }
  166.                     else {
  167.                         graphics.moveTo(p.x, p.y);
  168.                         graphics.lineTo(p.x + limit, p.y + limit);
  169.                     }
  170.                     
  171.                     p.px = p.x;
  172.                     p.py = p.y;
  173.                 }
  174.                 else {
  175.                     p.x = p.px = Math.random() * canvasWidth;
  176.                     p.y = p.py = Math.random() * canvasHeight;
  177.                     p.xvel = 0;
  178.                     p.yvel = 0;
  179.                 }
  180.                 
  181.                 p.xvel *= 0.5;
  182.                 p.yvel *= 0.5;
  183.             }
  184.         }
  185.         
  186.         /**
  187.          * マウスドラッグの処理
  188.          * @param    gridData
  189.          * @param    mvelX
  190.          * @param    mvelY
  191.          * @param    penSize
  192.          */
  193.         public function updateGridDataVelocity(gridData:GridData, mvelX:int, mvelY:int, penSize:Number):void {
  194.             var dx:Number = gridData.x - mouseX;
  195.             var dy:Number = gridData.y - mouseY;
  196.             var dist:Number = Math.sqrt(dy * dy + dx * dx);
  197.             
  198.             if (dist < penSize) { 
  199.                 if (dist < 4) {
  200.                     dist = penSize;
  201.                 }
  202.                 
  203.                 //マウスに近いほど力が強くなるように。
  204.                 var power:Number = penSize / dist;
  205.                 gridData.xvel += mvelX * power;
  206.                 gridData.yvel += mvelY * power;
  207.             }
  208.         }
  209.         
  210.         public function updatePressure(gridData:GridData):void {
  211.             var pressureX:Number = (
  212.                   gridData.upperLeft.xvel * 0.5 //左上
  213.                 + gridData.left.xvel       //左
  214.                 + gridData.lowerLeft.xvel * 0.5 //左下
  215.                 - gridData.upperRight.xvel * 0.5 //右上
  216.                 - gridData.right.xvel       //右
  217.                 - gridData.lowerRight.xvel * 0.5 //右下
  218.             );
  219.             
  220.             var pressureY:Number = (
  221.                   gridData.upperLeft.yvel * 0.5 //左上
  222.                 + gridData.up.yvel       //上
  223.                 + gridData.upperRight.yvel * 0.5 //右上
  224.                 - gridData.lowerLeft.yvel * 0.5 //左下
  225.                 - gridData.low.yvel       //下
  226.                 - gridData.lowerRight.yvel * 0.5 //右下
  227.             );
  228.             
  229.             gridData.pressure = (pressureX + pressureY) * 0.25;
  230.         }
  231.         
  232.         public function apdateVelocity(gridData:GridData):void {
  233.             gridData.xvel += (
  234.                   gridData.upperLeft.pressure * 0.5 //左上
  235.                 + gridData.left.pressure       //左
  236.                 + gridData.lowerLeft.pressure * 0.5 //左下
  237.                 - gridData.upperRight.pressure * 0.5 //右上
  238.                 - gridData.right.pressure       //右
  239.                 - gridData.lowerRight.pressure * 0.5 //右下
  240.             ) * 0.25;
  241.             
  242.             gridData.yvel += (
  243.                   gridData.upperLeft.pressure * 0.5 //左上
  244.                 + gridData.up.pressure       //上
  245.                 + gridData.upperRight.pressure * 0.5 //右上
  246.                 - gridData.lowerLeft.pressure * 0.5 //左下
  247.                 - gridData.low.pressure       //下
  248.                 - gridData.lowerRight.pressure * 0.5 //右下
  249.             ) * 0.25;
  250.             
  251.             gridData.xvel *= 0.99;
  252.             gridData.yvel *= 0.99;
  253.         }
  254.         
  255.         private function mouseDownHandler(e:Event):void {
  256.             mousePressed = true;
  257.         }
  258.         
  259.         private function mouseUpHandler(e:Event):void {
  260.             mousePressed = false;
  261.         }
  262.     }    
  263. }
  264. import flash.geom.Rectangle;
  265. class BaseGridData {
  266.     
  267.     public var col:int = 0;
  268.     public var row:int = 0;
  269.     
  270.     public var x:int = 0;
  271.     public var y:int = 0;
  272.     
  273.     public var xvel:Number = 0;
  274.     public var yvel:Number = 0;
  275.     
  276.     public var pressure:Number = 0;
  277.     
  278.     public var color:Number = 0;
  279.     public var rgb:uint;
  280.     public var rectangle:Rectangle;
  281. }
  282. class GridData extends BaseGridData{
  283.     
  284.     public function GridData(x:int, y:int, resolution:Number) {
  285.         this.x = x;
  286.         this.y = y;
  287.         rectangle = new Rectangle(x, y, resolution, resolution)
  288.     }
  289.     
  290.     //すべてのグリッドが8方向に隣接したグリッドを持つわけではないので、
  291.     //空のデータをセットしておく。
  292.     public var upperLeft:BaseGridData = new NullGridData();//左上
  293.     public var up:BaseGridData = new NullGridData();//上
  294.     public var upperRight:BaseGridData = new NullGridData();//右上
  295.     
  296.     public var left:BaseGridData = new NullGridData();//左
  297.     public var right:BaseGridData = new NullGridData();//右
  298.     
  299.     public var lowerLeft:BaseGridData = new NullGridData();//左下
  300.     public var low:BaseGridData = new NullGridData();//下
  301.     public var lowerRight:BaseGridData = new NullGridData();//右下    
  302. }
  303. class NullGridData extends BaseGridData{
  304. }
  305. class Particle {    
  306.     
  307.     public function Particle(x:Number, y:Number) {
  308.         this.x = px = x;
  309.         this.y = py = y;
  310.     }
  311.     
  312.     public var x:Number;
  313.     public var y:Number;
  314.     
  315.     public var px:Number;
  316.     public var py:Number;
  317.     public var xvel:Number = 0;
  318.     public var yvel:Number = 0;
  319.     
  320. }
noswf
  1. // forked from miniapp's 流体パーティクル
  2. /**
  3.  * Fluid \ Learning \ Processing 1.0
  4.  * http://www.processing.org/learning/topics/fluid.html
  5.  * 
  6.  * via [Flash]流体っぽいのを作ろうと思った | blog ViolentCoding
  7.  * http://violentcoding.com/blog/2008/07/26/archives/135
  8.  */
  9. package {
  10.     import flash.display.Bitmap;
  11.     import flash.display.BitmapData;
  12.     import flash.display.Sprite;
  13.     import flash.display.StageAlign;
  14.     import flash.display.StageQuality;
  15.     import flash.display.StageScaleMode;
  16.     import flash.events.Event;
  17.     import flash.events.MouseEvent;
  18.     import flash.geom.ColorTransform;
  19.     import flash.geom.Rectangle;
  20.     import net.hires.debug.Stats;
  21.     
  22.     [SWF(backgroundColor=0x0, width=465, height=465, frameRate=60)]
  23.     public class FluidLine extends Sprite {
  24.         
  25.         public function FluidLine() {
  26.             if (stage) init();
  27.             else addEventListener(Event.ADDED_TO_STAGE, init);
  28.         }
  29.         
  30.         private var pmouseX:Number;
  31.         private var pmouseY:Number;
  32.         private var canvasWidth:int = 465;
  33.         private var canvasHeight:int = 465;
  34.         private var mousePressed:Boolean;
  35.         private var resolution:int = 5;
  36.         private var penSize:int = 80;
  37.         private var numCols:int = canvasWidth / resolution;;
  38.         private var numRows:int = canvasHeight / resolution;
  39.         private var numParticles:int = 2000;
  40.         private var gridDatasVectors:Vector.<Vector.<GridData>> = new Vector.<Vector.<GridData>>();
  41.         private var particles:Vector.<Particle> = new Vector.<Particle>(numParticles, true);
  42.         private var pcount:int = 0;
  43.         
  44.         private function init(e:Event = null):void {
  45.             removeEventListener(Event.ADDED_TO_STAGE, init);
  46.             stage.scaleMode = StageScaleMode.NO_SCALE;
  47.             stage.align = StageAlign.TOP_LEFT;
  48.             
  49.             stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
  50.             stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
  51.             
  52. Wonderfl.capture_delay(5);
  53.             //stage.quality = StageQuality.MEDIUM;
  54.             //addChild(new Stats());
  55.             
  56.             for (var i:int = 0; i < numParticles; i++) {
  57.                 particles[i] = new Particle(Math.random() * canvasWidth, Math.random() * canvasHeight);
  58.             }
  59.             
  60.             for (var col:int = 0; col < numCols; ++col) { 
  61.                 gridDatasVectors[col] = new Vector.<GridData>(numRows, true);
  62.                 for (var row:int = 0; row < numRows; ++row) { 
  63.                     var gridData:GridData = new GridData(col * resolution, row * resolution, resolution);
  64.                     gridData.col = col;
  65.                     gridData.row = row;
  66.                     gridDatasVectors[col][row] = gridData;
  67.                 }
  68.             }
  69.             
  70.             //隣接するグリッドをセットしていく。
  71.             for (col = 0; col < numCols; ++col) { 
  72.                 for (row = 0; row < numRows; ++row) { 
  73.                     gridData = gridDatasVectors[col][row];
  74.                     if (row > 0) {
  75.                         var up:GridData = gridDatasVectors[col][row - 1];//上
  76.                         gridData.up = up;
  77.                         up.low = gridData;//下
  78.                     }
  79.                     
  80.                     if (col > 0) {
  81.                         var left:GridData = gridDatasVectors[col - 1][row];//左
  82.                         gridData.left = left;
  83.                         left.right = gridData;//右
  84.                     }
  85.                     
  86.                     if (row > 0 && col > 0) {
  87.                         var upperLeft:GridData = gridDatasVectors[col - 1][row - 1];
  88.                         gridData.upperLeft = upperLeft;
  89.                         upperLeft.lowerRight = gridData;
  90.                     }
  91.                     
  92.                     if (row > 0 && col < numCols - 1) {
  93.                         var upperRight:GridData = gridDatasVectors[col + 1][row - 1];
  94.                         gridData.upperRight = upperRight;
  95.                         upperRight.lowerLeft = gridData;
  96.                     }
  97.                 }
  98.             }
  99.             
  100.             gridDatasVectors.fixed = true;
  101.             addEventListener(Event.ENTER_FRAME, draw);
  102.         }
  103.         
  104.         private function draw(e:Event):void {
  105.             var mouseXvel:Number = mouseX - pmouseX;
  106.             var mouseYvel:Number = mouseY - pmouseY;
  107.             
  108.             for each(var gridDatas:Vector.<GridData> in gridDatasVectors) {
  109.                 for each(var gridData:GridData in gridDatas) {
  110.                     if (mousePressed) {
  111.                         updateGridDataVelocity(gridData, mouseXvel, mouseYvel, penSize);
  112.                     }
  113.                     updatePressure(gridData);
  114.                     
  115.                 }
  116.             }
  117.             
  118.             graphics.clear();
  119.             graphics.lineStyle(1, 0xFFFFFF);
  120.             updateParticle();
  121.             
  122.             for each(gridDatas in gridDatasVectors) {
  123.                 for each(gridData in gridDatas) {
  124.                     apdateVelocity(gridData);
  125.                 }
  126.             }
  127.             
  128.             pmouseX = mouseX;
  129.             pmouseY = mouseY;
  130.         }
  131.         
  132.         public function updateParticle():void {
  133.             for each(var p:Particle in particles) {
  134.                 if (p.x >= 0 && p.x < canvasWidth && p.y >= 0 && p.y < canvasHeight) {
  135.                     var col:int = int(p.x / resolution);//自身が属しているgridDataを見つける
  136.                     var row:int = int(p.y / resolution);
  137.                     
  138.                     if (col > numCols - 1) col = numCols - 1;
  139.                     if (row > numRows - 1) row = numRows - 1;
  140.                     
  141.                     var gridData:GridData = gridDatasVectors[col][row];
  142.                     
  143.                     var ax:Number = (p.x % resolution) / resolution;
  144.                     var ay:Number = (p.y % resolution) / resolution;
  145.                     p.xvel += (1 - ax) * gridData.xvel * 0.05;
  146.                     p.yvel += (1 - ay) * gridData.yvel * 0.05;
  147.                     
  148.                     p.xvel += ax * gridData.right.xvel * 0.05;
  149.                     p.yvel += ax * gridData.right.yvel * 0.05;
  150.                     
  151.                     p.xvel += ay * gridData.low.xvel * 0.05;
  152.                     p.yvel += ay * gridData.low.yvel * 0.05;
  153.                     
  154.                     p.x += p.xvel;
  155.                     p.y += p.yvel;
  156.                     
  157.                     var dx:Number = p.px - p.x;
  158.                     var dy:Number = p.py - p.y;
  159.                     var dist:Number = Math.sqrt(dx * dx + dy * dy);
  160.                     var limit:Number = Math.random() * 0.5;
  161.                     
  162.                     if (dist > limit) {
  163.                         graphics.moveTo(p.x, p.y);
  164.                         graphics.lineTo(p.px, p.py);
  165.                     }
  166.                     else {
  167.                         graphics.moveTo(p.x, p.y);
  168.                         graphics.lineTo(p.x + limit, p.y + limit);
  169.                     }
  170.                     
  171.                     p.px = p.x;
  172.                     p.py = p.y;
  173.                 }
  174.                 else {
  175.                     p.x = p.px = Math.random() * canvasWidth;
  176.                     p.y = p.py = Math.random() * canvasHeight;
  177.                     p.xvel = 0;
  178.                     p.yvel = 0;
  179.                 }
  180.                 
  181.                 p.xvel *= 0.5;
  182.                 p.yvel *= 0.5;
  183.             }
  184.         }
  185.         
  186.         /**
  187.          * マウスドラッグの処理
  188.          * @param    gridData
  189.          * @param    mvelX
  190.          * @param    mvelY
  191.          * @param    penSize
  192.          */
  193.         public function updateGridDataVelocity(gridData:GridData, mvelX:int, mvelY:int, penSize:Number):void {
  194.             var dx:Number = gridData.x - mouseX;
  195.             var dy:Number = gridData.y - mouseY;
  196.             var dist:Number = Math.sqrt(dy * dy + dx * dx);
  197.             
  198.             if (dist < penSize) { 
  199.                 if (dist < 16) {
  200.                     dist = penSize;
  201.                 }
  202.                 
  203.                 //マウスに近いほど力が強くなるように。
  204.                 var power:Number = penSize / dist;
  205.                 gridData.xvel += mvelX * power;
  206.                 gridData.yvel += mvelY * power;
  207.             }
  208.         }
  209.         
  210.         public function updatePressure(gridData:GridData):void {
  211.             var pressureX:Number = (
  212.                   gridData.upperLeft.xvel * 0.5 //左上
  213.                 + gridData.left.xvel       //左
  214.                 + gridData.lowerLeft.xvel * 0.5 //左下
  215.                 - gridData.upperRight.xvel * 0.5 //右上
  216.                 - gridData.right.xvel       //右
  217.                 - gridData.lowerRight.xvel * 0.5 //右下
  218.             );
  219.             
  220.             var pressureY:Number = (
  221.                   gridData.upperLeft.yvel * 0.5 //左上
  222.                 + gridData.up.yvel       //上
  223.                 + gridData.upperRight.yvel * 0.5 //右上
  224.                 - gridData.lowerLeft.yvel * 0.5 //左下
  225.                 - gridData.low.yvel       //下
  226.                 - gridData.lowerRight.yvel * 0.5 //右下
  227.             );
  228.             
  229.             gridData.pressure = (pressureX + pressureY) * 0.25;
  230.         }
  231.         
  232.         public function apdateVelocity(gridData:GridData):void {
  233.             gridData.xvel += (
  234.                   gridData.upperLeft.pressure * 0.5 //左上
  235.                 + gridData.left.pressure       //左
  236.                 + gridData.lowerLeft.pressure * 0.5 //左下
  237.                 - gridData.upperRight.pressure * 0.5 //右上
  238.                 - gridData.right.pressure       //右
  239.                 - gridData.lowerRight.pressure * 0.5 //右下
  240.             ) * 0.25;
  241.             
  242.             gridData.yvel += (
  243.                   gridData.upperLeft.pressure * 0.5 //左上
  244.                 + gridData.up.pressure       //上
  245.                 + gridData.upperRight.pressure * 0.5 //右上
  246.                 - gridData.lowerLeft.pressure * 0.5 //左下
  247.                 - gridData.low.pressure       //下
  248.                 - gridData.lowerRight.pressure * 0.5 //右下
  249.             ) * 0.25;
  250.             
  251.             gridData.xvel *= 0.99;
  252.             gridData.yvel *= 0.99;
  253.         }
  254.         
  255.         private function mouseDownHandler(e:Event):void {
  256.             mousePressed = true;
  257.         }
  258.         
  259.         private function mouseUpHandler(e:Event):void {
  260.             mousePressed = false;
  261.         }
  262.     }    
  263. }
  264. import flash.geom.Rectangle;
  265. class BaseGridData {
  266.     
  267.     public var col:int = 0;
  268.     public var row:int = 0;
  269.     
  270.     public var x:int = 0;
  271.     public var y:int = 0;
  272.     
  273.     public var xvel:Number = 0;
  274.     public var yvel:Number = 0;
  275.     
  276.     public var pressure:Number = 0;
  277.     
  278.     public var color:Number = 0;
  279.     public var rgb:uint;
  280.     public var rectangle:Rectangle;
  281. }
  282. class GridData extends BaseGridData{
  283.     
  284.     public function GridData(x:int, y:int, resolution:Number) {
  285.         this.x = x;
  286.         this.y = y;
  287.         rectangle = new Rectangle(x, y, resolution, resolution)
  288.     }
  289.     
  290.     //すべてのグリッドが8方向に隣接したグリッドを持つわけではないので、
  291.     //空のデータをセットしておく。
  292.     public var upperLeft:BaseGridData = new NullGridData();//左上
  293.     public var up:BaseGridData = new NullGridData();//上
  294.     public var upperRight:BaseGridData = new NullGridData();//右上
  295.     
  296.     public var left:BaseGridData = new NullGridData();//左
  297.     public var right:BaseGridData = new NullGridData();//右
  298.     
  299.     public var lowerLeft:BaseGridData = new NullGridData();//左下
  300.     public var low:BaseGridData = new NullGridData();//下
  301.     public var lowerRight:BaseGridData = new NullGridData();//右下    
  302. }
  303. class NullGridData extends BaseGridData{
  304. }
  305. class Particle {    
  306.     
  307.     public function Particle(x:Number, y:Number) {
  308.         this.x = px = x;
  309.         this.y = py = y;
  310.     }
  311.     
  312.     public var x:Number;
  313.     public var y:Number;
  314.     
  315.     public var px:Number;
  316.     public var py:Number;
  317.     public var xvel:Number = 0;
  318.     public var yvel:Number = 0;
  319.     
  320. }
noswf
  1. // forked from miniapp's 流体パーティクル
  2. /**
  3.  * Fluid \ Learning \ Processing 1.0
  4.  * http://www.processing.org/learning/topics/fluid.html
  5.  * 
  6.  * via [Flash]流体っぽいのを作ろうと思った | blog ViolentCoding
  7.  * http://violentcoding.com/blog/2008/07/26/archives/135
  8.  */
  9. package {
  10.     import flash.display.Bitmap;
  11.     import flash.display.BitmapData;
  12.     import flash.display.Sprite;
  13.     import flash.display.StageAlign;
  14.     import flash.display.StageQuality;
  15.     import flash.display.StageScaleMode;
  16.     import flash.events.Event;
  17.     import flash.events.MouseEvent;
  18.     import flash.geom.ColorTransform;
  19.     import flash.geom.Rectangle;
  20.     import net.hires.debug.Stats;
  21.     
  22.     [SWF(backgroundColor=0x0, width=465, height=465, frameRate=60)]
  23.     public class FluidLine extends Sprite {
  24.         
  25.         public function FluidLine() {
  26.             if (stage) init();
  27.             else addEventListener(Event.ADDED_TO_STAGE, init);
  28.         }
  29.         
  30.         private var pmouseX:Number;
  31.         private var pmouseY:Number;
  32.         private var canvasWidth:int = 465;
  33.         private var canvasHeight:int = 465;
  34.         private var mousePressed:Boolean;
  35.         private var resolution:int = 10;
  36.         private var penSize:int = 40;
  37.         private var numCols:int = canvasWidth / resolution;;
  38.         private var numRows:int = canvasHeight / resolution;
  39.         private var numParticles:int = 6000;
  40.         private var gridDatasVectors:Vector.<Vector.<GridData>> = new Vector.<Vector.<GridData>>();
  41.         private var particles:Vector.<Particle> = new Vector.<Particle>(numParticles, true);
  42.         private var pcount:int = 0;
  43.         
  44.         private function init(e:Event = null):void {
  45.             removeEventListener(Event.ADDED_TO_STAGE, init);
  46.             stage.scaleMode = StageScaleMode.NO_SCALE;
  47.             stage.align = StageAlign.TOP_LEFT;
  48.             
  49.             stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
  50.             stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
  51.             
  52. Wonderfl.capture_delay(5);
  53.             //stage.quality = StageQuality.MEDIUM;
  54.             //addChild(new Stats());
  55.             
  56.             for (var i:int = 0; i < numParticles; i++) {
  57.                 particles[i] = new Particle(Math.random() * canvasWidth, Math.random() * canvasHeight);
  58.             }
  59.             
  60.             for (var col:int = 0; col < numCols; ++col) { 
  61.                 gridDatasVectors[col] = new Vector.<GridData>(numRows, true);
  62.                 for (var row:int = 0; row < numRows; ++row) { 
  63.                     var gridData:GridData = new GridData(col * resolution, row * resolution, resolution);
  64.                     gridData.col = col;
  65.                     gridData.row = row;
  66.                     gridDatasVectors[col][row] = gridData;
  67.                 }
  68.             }
  69.             
  70.             //隣接するグリッドをセットしていく。
  71.             for (col = 0; col < numCols; ++col) { 
  72.                 for (row = 0; row < numRows; ++row) { 
  73.                     gridData = gridDatasVectors[col][row];
  74.                     if (row > 0) {
  75.                         var up:GridData = gridDatasVectors[col][row - 1];//上
  76.                         gridData.up = up;
  77.                         up.low = gridData;//下
  78.                     }
  79.                     
  80.                     if (col > 0) {
  81.                         var left:GridData = gridDatasVectors[col - 1][row];//左
  82.                         gridData.left = left;
  83.                         left.right = gridData;//右
  84.                     }
  85.                     
  86.                     if (row > 0 && col > 0) {
  87.                         var upperLeft:GridData = gridDatasVectors[col - 1][row - 1];
  88.                         gridData.upperLeft = upperLeft;
  89.                         upperLeft.lowerRight = gridData;
  90.                     }
  91.                     
  92.                     if (row > 0 && col < numCols - 1) {
  93.                         var upperRight:GridData = gridDatasVectors[col + 1][row - 1];
  94.                         gridData.upperRight = upperRight;
  95.                         upperRight.lowerLeft = gridData;
  96.                     }
  97.                 }
  98.             }
  99.             
  100.             gridDatasVectors.fixed = true;
  101.             addEventListener(Event.ENTER_FRAME, draw);
  102.         }
  103.         
  104.         private function draw(e:Event):void {
  105.             var mouseXvel:Number = mouseX - pmouseX;
  106.             var mouseYvel:Number = mouseY - pmouseY;
  107.             
  108.             for each(var gridDatas:Vector.<GridData> in gridDatasVectors) {
  109.                 for each(var gridData:GridData in gridDatas) {
  110.                     if (mousePressed) {
  111.                         updateGridDataVelocity(gridData, mouseXvel, mouseYvel, penSize);
  112.                     }
  113.                     updatePressure(gridData);
  114.                     
  115.                 }
  116.             }
  117.             
  118.             graphics.clear();
  119.             graphics.lineStyle(1, 0xFFFFFF);
  120.             updateParticle();
  121.             
  122.             for each(gridDatas in gridDatasVectors) {
  123.                 for each(gridData in gridDatas) {
  124.                     apdateVelocity(gridData);
  125.                 }
  126.             }
  127.             
  128.             pmouseX = mouseX;
  129.             pmouseY = mouseY;
  130.         }
  131.         
  132.         public function updateParticle():void {
  133.             for each(var p:Particle in particles) {
  134.                 if (p.x >= 0 && p.x < canvasWidth && p.y >= 0 && p.y < canvasHeight) {
  135.                     var col:int = int(p.x / resolution);//自身が属しているgridDataを見つける
  136.                     var row:int = int(p.y / resolution);
  137.                     
  138.                     if (col > numCols - 1) col = numCols - 1;
  139.                     if (row > numRows - 1) row = numRows - 1;
  140.                     
  141.                     var gridData:GridData = gridDatasVectors[col][row];
  142.                     
  143.                     var ax:Number = (p.x % resolution) / resolution;
  144.                     var ay:Number = (p.y % resolution) / resolution;
  145.                     p.xvel += (1 - ax) * gridData.xvel * 0.05;
  146.                     p.yvel += (1 - ay) * gridData.yvel * 0.05;
  147.                     
  148.                     p.xvel += ax * gridData.right.xvel * 0.05;
  149.                     p.yvel += ax * gridData.right.yvel * 0.05;
  150.                     
  151.                     p.xvel += ay * gridData.low.xvel * 0.05;
  152.                     p.yvel += ay * gridData.low.yvel * 0.05;
  153.                     
  154.                     p.x += p.xvel;
  155.                     p.y += p.yvel;
  156.                     
  157.                     var dx:Number = p.px - p.x;
  158.                     var dy:Number = p.py - p.y;
  159.                     var dist:Number = Math.sqrt(dx * dx + dy * dy);
  160.                     var limit:Number = Math.random() * 0.5;
  161.                     
  162.                     if (dist > limit) {
  163.                         graphics.moveTo(p.x, p.y);
  164.                         graphics.lineTo(p.px, p.py);
  165.                     }
  166.                     else {
  167.                         graphics.moveTo(p.x, p.y);
  168.                         graphics.lineTo(p.x + limit, p.y + limit);
  169.                     }
  170.                     
  171.                     p.px = p.x;
  172.                     p.py = p.y;
  173.                 }
  174.                 else {
  175.                     p.x = p.px = Math.random() * canvasWidth;
  176.                     p.y = p.py = Math.random() * canvasHeight;
  177.                     p.xvel = 0;
  178.                     p.yvel = 0;
  179.                 }
  180.                 
  181.                 p.xvel *= 0.5;
  182.                 p.yvel *= 0.5;
  183.             }
  184.         }
  185.         
  186.         /**
  187.          * マウスドラッグの処理
  188.          * @param    gridData
  189.          * @param    mvelX
  190.          * @param    mvelY
  191.          * @param    penSize
  192.          */
  193.         public function updateGridDataVelocity(gridData:GridData, mvelX:int, mvelY:int, penSize:Number):void {
  194.             var dx:Number = gridData.x - mouseX;
  195.             var dy:Number = gridData.y - mouseY;
  196.             var dist:Number = Math.sqrt(dy * dy + dx * dx);
  197.             
  198.             if (dist < penSize) { 
  199.                 if (dist < 4) {
  200.                     dist = penSize;
  201.                 }
  202.                 
  203.                 //マウスに近いほど力が強くなるように。
  204.                 var power:Number = penSize / dist;
  205.                 gridData.xvel += mvelX * power;
  206.                 gridData.yvel += mvelY * power;
  207.             }
  208.         }
  209.         
  210.         public function updatePressure(gridData:GridData):void {
  211.             var pressureX:Number = (
  212.                   gridData.upperLeft.xvel * 0.5 //左上
  213.                 + gridData.left.xvel       //左
  214.                 + gridData.lowerLeft.xvel * 0.5 //左下
  215.                 - gridData.upperRight.xvel * 0.5 //右上
  216.                 - gridData.right.xvel       //右
  217.                 - gridData.lowerRight.xvel * 0.5 //右下
  218.             );
  219.             
  220.             var pressureY:Number = (
  221.                   gridData.upperLeft.yvel * 0.5 //左上
  222.                 + gridData.up.yvel       //上
  223.                 + gridData.upperRight.yvel * 0.5 //右上
  224.                 - gridData.lowerLeft.yvel * 0.5 //左下
  225.                 - gridData.low.yvel       //下
  226.                 - gridData.lowerRight.yvel * 0.5 //右下
  227.             );
  228.             
  229.             gridData.pressure = (pressureX + pressureY) * 0.25;
  230.         }
  231.         
  232.         public function apdateVelocity(gridData:GridData):void {
  233.             gridData.xvel += (
  234.                   gridData.upperLeft.pressure * 0.5 //左上
  235.                 + gridData.left.pressure       //左
  236.                 + gridData.lowerLeft.pressure * 0.5 //左下
  237.                 - gridData.upperRight.pressure * 0.5 //右上
  238.                 - gridData.right.pressure       //右
  239.                 - gridData.lowerRight.pressure * 0.5 //右下
  240.             ) * 0.25;
  241.             
  242.             gridData.yvel += (
  243.                   gridData.upperLeft.pressure * 0.5 //左上
  244.                 + gridData.up.pressure       //上
  245.                 + gridData.upperRight.pressure * 0.5 //右上
  246.                 - gridData.lowerLeft.pressure * 0.5 //左下
  247.                 - gridData.low.pressure       //下
  248.                 - gridData.lowerRight.pressure * 0.5 //右下
  249.             ) * 0.25;
  250.             
  251.             gridData.xvel *= 0.99;
  252.             gridData.yvel *= 0.99;
  253.         }
  254.         
  255.         private function mouseDownHandler(e:Event):void {
  256.             mousePressed = true;
  257.         }
  258.         
  259.         private function mouseUpHandler(e:Event):void {
  260.             mousePressed = false;
  261.         }
  262.     }    
  263. }
  264. import flash.geom.Rectangle;
  265. class BaseGridData {
  266.     
  267.     public var col:int = 0;
  268.     public var row:int = 0;
  269.     
  270.     public var x:int = 0;
  271.     public var y:int = 0;
  272.     
  273.     public var xvel:Number = 0;
  274.     public var yvel:Number = 0;
  275.     
  276.     public var pressure:Number = 0;
  277.     
  278.     public var color:Number = 0;
  279.     public var rgb:uint;
  280.     public var rectangle:Rectangle;
  281. }
  282. class GridData extends BaseGridData{
  283.     
  284.     public function GridData(x:int, y:int, resolution:Number) {
  285.         this.x = x;
  286.         this.y = y;
  287.         rectangle = new Rectangle(x, y, resolution, resolution)
  288.     }
  289.     
  290.     //すべてのグリッドが8方向に隣接したグリッドを持つわけではないので、
  291.     //空のデータをセットしておく。
  292.     public var upperLeft:BaseGridData = new NullGridData();//左上
  293.     public var up:BaseGridData = new NullGridData();//上
  294.     public var upperRight:BaseGridData = new NullGridData();//右上
  295.     
  296.     public var left:BaseGridData = new NullGridData();//左
  297.     public var right:BaseGridData = new NullGridData();//右
  298.     
  299.     public var lowerLeft:BaseGridData = new NullGridData();//左下
  300.     public var low:BaseGridData = new NullGridData();//下
  301.     public var lowerRight:BaseGridData = new NullGridData();//右下    
  302. }
  303. class NullGridData extends BaseGridData{
  304. }
  305. class Particle {    
  306.     
  307.     public function Particle(x:Number, y:Number) {
  308.         this.x = px = x;
  309.         this.y = py = y;
  310.     }
  311.     
  312.     public var x:Number;
  313.     public var y:Number;
  314.     
  315.     public var px:Number;
  316.     public var py:Number;
  317.     public var xvel:Number = 0;
  318.     public var yvel:Number = 0;
  319.     
  320. }
noswf
  1. // forked from miniapp's 流体パーティクル
  2. /**
  3.  * Fluid \ Learning \ Processing 1.0
  4.  * http://www.processing.org/learning/topics/fluid.html
  5.  * 
  6.  * via [Flash]流体っぽいのを作ろうと思った | blog ViolentCoding
  7.  * http://violentcoding.com/blog/2008/07/26/archives/135
  8.  */
  9. package {
  10.     import flash.display.Bitmap;
  11.     import flash.display.BitmapData;
  12.     import flash.display.Sprite;
  13.     import flash.display.StageAlign;
  14.     import flash.display.StageQuality;
  15.     import flash.display.StageScaleMode;
  16.     import flash.events.Event;
  17.     import flash.events.MouseEvent;
  18.     import flash.geom.ColorTransform;
  19.     import flash.geom.Rectangle;
  20.     import net.hires.debug.Stats;
  21.     
  22.     [SWF(backgroundColor=0x0, width=465, height=465, frameRate=60)]
  23.     public class FluidLine extends Sprite {
  24.         
  25.         public function FluidLine() {
  26.             if (stage) init();
  27.             else addEventListener(Event.ADDED_TO_STAGE, init);
  28.         }
  29.         
  30.         private var pmouseX:Number;
  31.         private var pmouseY:Number;
  32.         private var canvasWidth:int = 465;
  33.         private var canvasHeight:int = 465;
  34.         private var mousePressed:Boolean;
  35.         private var resolution:int = 10;
  36.         private var penSize:int = 40;
  37.         private var numCols:int = canvasWidth / resolution;;
  38.         private var numRows:int = canvasHeight / resolution;
  39.         private var numParticles:int = 6000;
  40.         private var gridDatasVectors:Vector.<Vector.<GridData>> = new Vector.<Vector.<GridData>>();
  41.         private var particles:Vector.<Particle> = new Vector.<Particle>(numParticles, true);
  42.         private var pcount:int = 0;
  43.         
  44.         private function init(e:Event = null):void {
  45.             removeEventListener(Event.ADDED_TO_STAGE, init);
  46.             stage.scaleMode = StageScaleMode.NO_SCALE;
  47.             stage.align = StageAlign.TOP_LEFT;
  48.             
  49.             stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
  50.             stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
  51.             
  52. Wonderfl.capture_delay(5);
  53.             //stage.quality = StageQuality.MEDIUM;
  54.             //addChild(new Stats());
  55.             
  56.             for (var i:int = 0; i < numParticles; i++) {
  57.                 particles[i] = new Particle(Math.random() * canvasWidth, Math.random() * canvasHeight);
  58.             }
  59.             
  60.             for (var col:int = 0; col < numCols; ++col) { 
  61.                 gridDatasVectors[col] = new Vector.<GridData>(numRows, true);
  62.                 for (var row:int = 0; row < numRows; ++row) { 
  63.                     var gridData:GridData = new GridData(col * resolution, row * resolution, resolution);
  64.                     gridData.col = col;
  65.                     gridData.row = row;
  66.                     gridDatasVectors[col][row] = gridData;
  67.                 }
  68.             }
  69.             
  70.             //隣接するグリッドをセットしていく。
  71.             for (col = 0; col < numCols; ++col) { 
  72.                 for (row = 0; row < numRows; ++row) { 
  73.                     gridData = gridDatasVectors[col][row];
  74.                     if (row > 0) {
  75.                         var up:GridData = gridDatasVectors[col][row - 1];//上
  76.                         gridData.up = up;
  77.                         up.low = gridData;//下
  78.                     }
  79.                     
  80.                     if (col > 0) {
  81.                         var left:GridData = gridDatasVectors[col - 1][row];//左
  82.                         gridData.left = left;
  83.                         left.right = gridData;//右
  84.                     }
  85.                     
  86.                     if (row > 0 && col > 0) {
  87.                         var upperLeft:GridData = gridDatasVectors[col - 1][row - 1];
  88.                         gridData.upperLeft = upperLeft;
  89.                         upperLeft.lowerRight = gridData;
  90.                     }
  91.                     
  92.                     if (row > 0 && col < numCols - 1) {
  93.                         var upperRight:GridData = gridDatasVectors[col + 1][row - 1];
  94.                         gridData.upperRight = upperRight;
  95.                         upperRight.lowerLeft = gridData;
  96.                     }
  97.                 }
  98.             }
  99.             
  100.             gridDatasVectors.fixed = true;
  101.             addEventListener(Event.ENTER_FRAME, draw);
  102.         }
  103.         
  104.         private function draw(e:Event):void {
  105.             var mouseXvel:Number = mouseX - pmouseX;
  106.             var mouseYvel:Number = mouseY - pmouseY;
  107.             
  108.             for each(var gridDatas:Vector.<GridData> in gridDatasVectors) {
  109.                 for each(var gridData:GridData in gridDatas) {
  110.                     if (mousePressed) {
  111.                         updateGridDataVelocity(gridData, mouseXvel, mouseYvel, penSize);
  112.                     }
  113.                     updatePressure(gridData);
  114.                     
  115.                 }
  116.             }
  117.             
  118.             graphics.clear();
  119.             graphics.lineStyle(1, 0xFFFFFF);
  120.             updateParticle();
  121.             
  122.             for each(gridDatas in gridDatasVectors) {
  123.                 for each(gridData in gridDatas) {
  124.                     apdateVelocity(gridData);
  125.                 }
  126.             }
  127.             
  128.             pmouseX = mouseX;
  129.             pmouseY = mouseY;
  130.         }
  131.         
  132.         public function updateParticle():void {
  133.             for each(var p:Particle in particles) {
  134.                 if (p.x >= 0 && p.x < canvasWidth && p.y >= 0 && p.y < canvasHeight) {
  135.                     var col:int = int(p.x / resolution);//自身が属しているgridDataを見つける
  136.                     var row:int = int(p.y / resolution);
  137.                     
  138.                     if (col > numCols - 1) col = numCols - 1;
  139.                     if (row > numRows - 1) row = numRows - 1;
  140.                     
  141.                     var gridData:GridData = gridDatasVectors[col][row];
  142.                     
  143.                     var ax:Number = (p.x % resolution) / resolution;
  144.                     var ay:Number = (p.y % resolution) / resolution;
  145.                     p.xvel += (1 - ax) * gridData.xvel * 0.05;
  146.                     p.yvel += (1 - ay) * gridData.yvel * 0.05;
  147.                     
  148.                     p.xvel += ax * gridData.right.xvel * 0.05;
  149.                     p.yvel += ax * gridData.right.yvel * 0.05;
  150.                     
  151.                     p.xvel += ay * gridData.low.xvel * 0.05;
  152.                     p.yvel += ay * gridData.low.yvel * 0.05;
  153.                     
  154.                     p.x += p.xvel;
  155.                     p.y += p.yvel;
  156.                     
  157.                     var dx:Number = p.px - p.x;
  158.                     var dy:Number = p.py - p.y;
  159.                     var dist:Number = Math.sqrt(dx * dx + dy * dy);
  160.                     var limit:Number = Math.random() * 0.5;
  161.                     
  162.                     if (dist > limit) {
  163.                         graphics.moveTo(p.x, p.y);
  164.                         graphics.lineTo(p.px, p.py);
  165.                     }
  166.                     else {
  167.                         graphics.moveTo(p.x, p.y);
  168.                         graphics.lineTo(p.x + limit, p.y + limit);
  169.                     }
  170.                     
  171.                     p.px = p.x;
  172.                     p.py = p.y;
  173.                 }
  174.                 else {
  175.                     p.x = p.px = Math.random() * canvasWidth;
  176.                     p.y = p.py = Math.random() * canvasHeight;
  177.                     p.xvel = 0;
  178.                     p.yvel = 0;
  179.                 }
  180.                 
  181.                 p.xvel *= 0.5;
  182.                 p.yvel *= 0.5;
  183.             }
  184.         }
  185.         
  186.         /**
  187.          * マウスドラッグの処理
  188.          * @param    gridData
  189.          * @param    mvelX
  190.          * @param    mvelY
  191.          * @param    penSize
  192.          */
  193.         public function updateGridDataVelocity(gridData:GridData, mvelX:int, mvelY:int, penSize:Number):void {
  194.             var dx:Number = gridData.x - mouseX;
  195.             var dy:Number = gridData.y - mouseY;
  196.             var dist:Number = Math.sqrt(dy * dy + dx * dx);
  197.             
  198.             if (dist < penSize) { 
  199.                 if (dist < 4) {
  200.                     dist = penSize;
  201.                 }
  202.                 
  203.                 //マウスに近いほど力が強くなるように。
  204.                 var power:Number = penSize / dist;
  205.                 gridData.xvel += mvelX * power;
  206.                 gridData.yvel += mvelY * power;
  207.             }
  208.         }
  209.         
  210.         public function updatePressure(gridData:GridData):void {
  211.             var pressureX:Number = (
  212.                   gridData.upperLeft.xvel * 0.5 //左上
  213.                 + gridData.left.xvel       //左
  214.                 + gridData.lowerLeft.xvel * 0.5 //左下
  215.                 - gridData.upperRight.xvel * 0.5 //右上
  216.                 - gridData.right.xvel       //右
  217.                 - gridData.lowerRight.xvel * 0.5 //右下
  218.             );
  219.             
  220.             var pressureY:Number = (
  221.                   gridData.upperLeft.yvel * 0.5 //左上
  222.                 + gridData.up.yvel       //上
  223.                 + gridData.upperRight.yvel * 0.5 //右上
  224.                 - gridData.lowerLeft.yvel * 0.5 //左下
  225.                 - gridData.low.yvel       //下
  226.                 - gridData.lowerRight.yvel * 0.5 //右下
  227.             );
  228.             
  229.             gridData.pressure = (pressureX + pressureY) * 0.25;
  230.         }
  231.         
  232.         public function apdateVelocity(gridData:GridData):void {
  233.             gridData.xvel += (
  234.                   gridData.upperLeft.pressure * 0.5 //左上
  235.                 + gridData.left.pressure       //左
  236.                 + gridData.lowerLeft.pressure * 0.5 //左下
  237.                 - gridData.upperRight.pressure * 0.5 //右上
  238.                 - gridData.right.pressure       //右
  239.                 - gridData.lowerRight.pressure * 0.5 //右下
  240.             ) * 0.25;
  241.             
  242.             gridData.yvel += (
  243.                   gridData.upperLeft.pressure * 0.5 //左上
  244.                 + gridData.up.pressure       //上
  245.                 + gridData.upperRight.pressure * 0.5 //右上
  246.                 - gridData.lowerLeft.pressure * 0.5 //左下
  247.                 - gridData.low.pressure       //下
  248.                 - gridData.lowerRight.pressure * 0.5 //右下
  249.             ) * 0.25;
  250.             
  251.             gridData.xvel *= 0.99;
  252.             gridData.yvel *= 0.99;
  253.         }
  254.         
  255.         private function mouseDownHandler(e:Event):void {
  256.             mousePressed = true;
  257.         }
  258.         
  259.         private function mouseUpHandler(e:Event):void {
  260.             mousePressed = false;
  261.         }
  262.     }    
  263. }
  264. import flash.geom.Rectangle;
  265. class BaseGridData {
  266.     
  267.     public var col:int = 0;
  268.     public var row:int = 0;
  269.     
  270.     public var x:int = 0;
  271.     public var y:int = 0;
  272.     
  273.     public var xvel:Number = 0;
  274.     public var yvel:Number = 0;
  275.     
  276.     public var pressure:Number = 0;
  277.     
  278.     public var color:Number = 0;
  279.     public var rgb:uint;
  280.     public var rectangle:Rectangle;
  281. }
  282. class GridData extends BaseGridData{
  283.     
  284.     public function GridData(x:int, y:int, resolution:Number) {
  285.         this.x = x;
  286.         this.y = y;
  287.         rectangle = new Rectangle(x, y, resolution, resolution)
  288.     }
  289.     
  290.     //すべてのグリッドが8方向に隣接したグリッドを持つわけではないので、
  291.     //空のデータをセットしておく。
  292.     public var upperLeft:BaseGridData = new NullGridData();//左上
  293.     public var up:BaseGridData = new NullGridData();//上
  294.     public var upperRight:BaseGridData = new NullGridData();//右上
  295.     
  296.     public var left:BaseGridData = new NullGridData();//左
  297.     public var right:BaseGridData = new NullGridData();//右
  298.     
  299.     public var lowerLeft:BaseGridData = new NullGridData();//左下
  300.     public var low:BaseGridData = new NullGridData();//下
  301.     public var lowerRight:BaseGridData = new NullGridData();//右下    
  302. }
  303. class NullGridData extends BaseGridData{
  304. }
  305. class Particle {    
  306.     
  307.     public function Particle(x:Number, y:Number) {
  308.         this.x = px = x;
  309.         this.y = py = y;
  310.     }
  311.     
  312.     public var x:Number;
  313.     public var y:Number;
  314.     
  315.     public var px:Number;
  316.     public var py:Number;
  317.     public var xvel:Number = 0;
  318.     public var yvel:Number = 0;
  319.     
  320. }
noswf
  1. // forked from miniapp's 流体パーティクル
  2. /**
  3.  * Fluid \ Learning \ Processing 1.0
  4.  * http://www.processing.org/learning/topics/fluid.html
  5.  * 
  6.  * via [Flash]流体っぽいのを作ろうと思った | blog ViolentCoding
  7.  * http://violentcoding.com/blog/2008/07/26/archives/135
  8.  */
  9. package {
  10.     import flash.display.Bitmap;
  11.     import flash.display.BitmapData;
  12.     import flash.display.Sprite;
  13.     import flash.display.StageAlign;
  14.     import flash.display.StageQuality;
  15.     import flash.display.StageScaleMode;
  16.     import flash.events.Event;
  17.     import flash.events.MouseEvent;
  18.     import flash.geom.ColorTransform;
  19.     import flash.geom.Rectangle;
  20.     import net.hires.debug.Stats;
  21.     
  22.     [SWF(backgroundColor=0x0, width=465, height=465, frameRate=60)]
  23.     public class FluidLine extends Sprite {
  24.         
  25.         public function FluidLine() {
  26.             if (stage) init();
  27.             else addEventListener(Event.ADDED_TO_STAGE, init);
  28.         }
  29.         
  30.         private var pmouseX:Number;
  31.         private var pmouseY:Number;
  32.         private var canvasWidth:int = 465;
  33.         private var canvasHeight:int = 465;
  34.         private var mousePressed:Boolean;
  35.         private var resolution:int = 10;
  36.         private var penSize:int = 40;
  37.         private var numCols:int = canvasWidth / resolution;;
  38.         private var numRows:int = canvasHeight / resolution;
  39.         private var numParticles:int = 6000;
  40.         private var gridDatasVectors:Vector.<Vector.<GridData>> = new Vector.<Vector.<GridData>>();
  41.         private var particles:Vector.<Particle> = new Vector.<Particle>(numParticles, true);
  42.         private var pcount:int = 0;
  43.         
  44.         private function init(e:Event = null):void {
  45.             removeEventListener(Event.ADDED_TO_STAGE, init);
  46.             stage.scaleMode = StageScaleMode.NO_SCALE;
  47.             stage.align = StageAlign.TOP_LEFT;
  48.             
  49.             stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
  50.             stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
  51.             
  52. Wonderfl.capture_delay(5);
  53.             //stage.quality = StageQuality.MEDIUM;
  54.             //addChild(new Stats());
  55.             
  56.             for (var i:int = 0; i < numParticles; i++) {
  57.                 particles[i] = new Particle(Math.random() * canvasWidth, Math.random() * canvasHeight);
  58.             }
  59.             
  60.             for (var col:int = 0; col < numCols; ++col) { 
  61.                 gridDatasVectors[col] = new Vector.<GridData>(numRows, true);
  62.                 for (var row:int = 0; row < numRows; ++row) { 
  63.                     var gridData:GridData = new GridData(col * resolution, row * resolution, resolution);
  64.                     gridData.col = col;
  65.                     gridData.row = row;
  66.                     gridDatasVectors[col][row] = gridData;
  67.                 }
  68.             }
  69.             
  70.             //隣接するグリッドをセットしていく。
  71.             for (col = 0; col < numCols; ++col) { 
  72.                 for (row = 0; row < numRows; ++row) { 
  73.                     gridData = gridDatasVectors[col][row];
  74.                     if (row > 0) {
  75.                         var up:GridData = gridDatasVectors[col][row - 1];//上
  76.                         gridData.up = up;
  77.                         up.low = gridData;//下
  78.                     }
  79.                     
  80.                     if (col > 0) {
  81.                         var left:GridData = gridDatasVectors[col - 1][row];//左
  82.                         gridData.left = left;
  83.                         left.right = gridData;//右
  84.                     }
  85.                     
  86.                     if (row > 0 && col > 0) {
  87.                         var upperLeft:GridData = gridDatasVectors[col - 1][row - 1];
  88.                         gridData.upperLeft = upperLeft;
  89.                         upperLeft.lowerRight = gridData;
  90.                     }
  91.                     
  92.                     if (row > 0 && col < numCols - 1) {
  93.                         var upperRight:GridData = gridDatasVectors[col + 1][row - 1];
  94.                         gridData.upperRight = upperRight;
  95.                         upperRight.lowerLeft = gridData;
  96.                     }
  97.                 }
  98.             }
  99.             
  100.             gridDatasVectors.fixed = true;
  101.             addEventListener(Event.ENTER_FRAME, draw);
  102.         }
  103.         
  104.         private function draw(e:Event):void {
  105.             var mouseXvel:Number = mouseX - pmouseX;
  106.             var mouseYvel:Number = mouseY - pmouseY;
  107.             
  108.             for each(var gridDatas:Vector.<GridData> in gridDatasVectors) {
  109.                 for each(var gridData:GridData in gridDatas) {
  110.                     if (mousePressed) {
  111.                         updateGridDataVelocity(gridData, mouseXvel, mouseYvel, penSize);
  112.                     }
  113.                     updatePressure(gridData);
  114.                     
  115.                 }
  116.             }
  117.             
  118.             graphics.clear();
  119.             graphics.lineStyle(1, 0xFFFFFF);
  120.             updateParticle();
  121.             
  122.             for each(gridDatas in gridDatasVectors) {
  123.                 for each(gridData in gridDatas) {
  124.                     apdateVelocity(gridData);
  125.                 }
  126.             }
  127.             
  128.             pmouseX = mouseX;
  129.             pmouseY = mouseY;
  130.         }
  131.         
  132.         public function updateParticle():void {
  133.             for each(var p:Particle in particles) {
  134.                 if (p.x >= 0 && p.x < canvasWidth && p.y >= 0 && p.y < canvasHeight) {
  135.                     var col:int = int(p.x / resolution);//自身が属しているgridDataを見つける
  136.                     var row:int = int(p.y / resolution);
  137.                     
  138.                     if (col > numCols - 1) col = numCols - 1;
  139.                     if (row > numRows - 1) row = numRows - 1;
  140.                     
  141.                     var gridData:GridData = gridDatasVectors[col][row];
  142.                     
  143.                     var ax:Number = (p.x % resolution) / resolution;
  144.                     var ay:Number = (p.y % resolution) / resolution;
  145.                     p.xvel += (1 - ax) * gridData.xvel * 0.05;
  146.                     p.yvel += (1 - ay) * gridData.yvel * 0.05;
  147.                     
  148.                     p.xvel += ax * gridData.right.xvel * 0.05;
  149.                     p.yvel += ax * gridData.right.yvel * 0.05;
  150.                     
  151.                     p.xvel += ay * gridData.low.xvel * 0.05;
  152.                     p.yvel += ay * gridData.low.yvel * 0.05;
  153.                     
  154.                     p.x += p.xvel;
  155.                     p.y += p.yvel;
  156.                     
  157.                     var dx:Number = p.px - p.x;
  158.                     var dy:Number = p.py - p.y;
  159.                     var dist:Number = Math.sqrt(dx * dx + dy * dy);
  160.                     var limit:Number = Math.random() * 0.5;
  161.                     
  162.                     if (dist > limit) {
  163.                         graphics.moveTo(p.x, p.y);
  164.                         graphics.lineTo(p.px, p.py);
  165.                     }
  166.                     else {
  167.                         graphics.moveTo(p.x, p.y);
  168.                         graphics.lineTo(p.x + limit, p.y + limit);
  169.                     }
  170.                     
  171.                     p.px = p.x;
  172.                     p.py = p.y;
  173.                 }
  174.                 else {
  175.                     p.x = p.px = Math.random() * canvasWidth;
  176.                     p.y = p.py = Math.random() * canvasHeight;
  177.                     p.xvel = 0;
  178.                     p.yvel = 0;
  179.                 }
  180.                 
  181.                 p.xvel *= 0.5;
  182.                 p.yvel *= 0.5;
  183.             }
  184.         }
  185.         
  186.         /**
  187.          * マウスドラッグの処理
  188.          * @param    gridData
  189.          * @param    mvelX
  190.          * @param    mvelY
  191.          * @param    penSize
  192.          */
  193.         public function updateGridDataVelocity(gridData:GridData, mvelX:int, mvelY:int, penSize:Number):void {
  194.             var dx:Number = gridData.x - mouseX;
  195.             var dy:Number = gridData.y - mouseY;
  196.             var dist:Number = Math.sqrt(dy * dy + dx * dx);
  197.             
  198.             if (dist < penSize) { 
  199.                 if (dist < 4) {
  200.                     dist = penSize;
  201.                 }
  202.                 
  203.                 //マウスに近いほど力が強くなるように。
  204.                 var power:Number = penSize / dist;
  205.                 gridData.xvel += mvelX * power;
  206.                 gridData.yvel += mvelY * power;
  207.             }
  208.         }
  209.         
  210.         public function updatePressure(gridData:GridData):void {
  211.             var pressureX:Number = (
  212.                   gridData.upperLeft.xvel * 0.5 //左上
  213.                 + gridData.left.xvel       //左
  214.                 + gridData.lowerLeft.xvel * 0.5 //左下
  215.                 - gridData.upperRight.xvel * 0.5 //右上
  216.                 - gridData.right.xvel       //右
  217.                 - gridData.lowerRight.xvel * 0.5 //右下
  218.             );
  219.             
  220.             var pressureY:Number = (
  221.                   gridData.upperLeft.yvel * 0.5 //左上
  222.                 + gridData.up.yvel       //上
  223.                 + gridData.upperRight.yvel * 0.5 //右上
  224.                 - gridData.lowerLeft.yvel * 0.5 //左下
  225.                 - gridData.low.yvel       //下
  226.                 - gridData.lowerRight.yvel * 0.5 //右下
  227.             );
  228.             
  229.             gridData.pressure = (pressureX + pressureY) * 0.25;
  230.         }
  231.         
  232.         public function apdateVelocity(gridData:GridData):void {
  233.             gridData.xvel += (
  234.                   gridData.upperLeft.pressure * 0.5 //左上
  235.                 + gridData.left.pressure       //左
  236.                 + gridData.lowerLeft.pressure * 0.5 //左下
  237.                 - gridData.upperRight.pressure * 0.5 //右上
  238.                 - gridData.right.pressure       //右
  239.                 - gridData.lowerRight.pressure * 0.5 //右下
  240.             ) * 0.25;
  241.             
  242.             gridData.yvel += (
  243.                   gridData.upperLeft.pressure * 0.5 //左上
  244.                 + gridData.up.pressure       //上
  245.                 + gridData.upperRight.pressure * 0.5 //右上
  246.                 - gridData.lowerLeft.pressure * 0.5 //左下
  247.                 - gridData.low.pressure       //下
  248.                 - gridData.lowerRight.pressure * 0.5 //右下
  249.             ) * 0.25;
  250.             
  251.             gridData.xvel *= 0.99;
  252.             gridData.yvel *= 0.99;
  253.         }
  254.         
  255.         private function mouseDownHandler(e:Event):void {
  256.             mousePressed = true;
  257.         }
  258.         
  259.         private function mouseUpHandler(e:Event):void {
  260.             mousePressed = false;
  261.         }
  262.     }    
  263. }
  264. import flash.geom.Rectangle;
  265. class BaseGridData {
  266.     
  267.     public var col:int = 0;
  268.     public var row:int = 0;
  269.     
  270.     public var x:int = 0;
  271.     public var y:int = 0;
  272.     
  273.     public var xvel:Number = 0;
  274.     public var yvel:Number = 0;
  275.     
  276.     public var pressure:Number = 0;
  277.     
  278.     public var color:Number = 0;
  279.     public var rgb:uint;
  280.     public var rectangle:Rectangle;
  281. }
  282. class GridData extends BaseGridData{
  283.     
  284.     public function GridData(x:int, y:int, resolution:Number) {
  285.         this.x = x;
  286.         this.y = y;
  287.         rectangle = new Rectangle(x, y, resolution, resolution)
  288.     }
  289.     
  290.     //すべてのグリッドが8方向に隣接したグリッドを持つわけではないので、
  291.     //空のデータをセットしておく。
  292.     public var upperLeft:BaseGridData = new NullGridData();//左上
  293.     public var up:BaseGridData = new NullGridData();//上
  294.     public var upperRight:BaseGridData = new NullGridData();//右上
  295.     
  296.     public var left:BaseGridData = new NullGridData();//左
  297.     public var right:BaseGridData = new NullGridData();//右
  298.     
  299.     public var lowerLeft:BaseGridData = new NullGridData();//左下
  300.     public var low:BaseGridData = new NullGridData();//下
  301.     public var lowerRight:BaseGridData = new NullGridData();//右下    
  302. }
  303. class NullGridData extends BaseGridData{
  304. }
  305. class Particle {    
  306.     
  307.     public function Particle(x:Number, y:Number) {
  308.         this.x = px = x;
  309.         this.y = py = y;
  310.     }
  311.     
  312.     public var x:Number;
  313.     public var y:Number;
  314.     
  315.     public var px:Number;
  316.     public var py:Number;
  317.     public var xvel:Number = 0;
  318.     public var yvel:Number = 0;
  319.     
  320. }
noswf
Get Adobe Flash Player