// forked from miniapp's Processingの流体サンプル /** * * ここのをas3に書き換えたもの。 * http://processing.org/learning/topics/fluid.html * **/ package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.display.StageQuality; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Rectangle; [SWF(backgroundColor="0x0", width="465", height="465", frameRate="30")] public class Main extends Sprite { public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private var pmouseX:Number; private var pmouseY:Number; private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler); stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler); stage.quality = StageQuality.MEDIUM; addChild(new Bitmap(canvas)); lwidth = width / res; lheight = height / res; v = new Vector.<Vector.<vsquare>>(lheight + 1); vbuf = new Vector.<Vector.<vbuffer>>(lheight + 1); for (var i:int = 0; i < pnum; i++) { p[i] = new particle(Math.random() * width, Math.random() * height); } for (i = 0; i <= lwidth; i++) { v[i] = new Vector.<vsquare>(lwidth + 1); vbuf[i] = new Vector.<vbuffer>(lwidth + 1); for (var u:int = 0; u <= lheight; u++) { v[i][u] = new vsquare(i * res, u * res); vbuf[i][u] = new vbuffer(i * res, u * res); } v[i].fixed = true;//付け足し vbuf[i].fixed = true;//付け足し } v.fixed = true;//付け足し vbuf.fixed = true;//付け足し addEventListener(Event.ENTER_FRAME, draw); } private function draw(e:Event):void { mouseX = this.mouseX; mouseY = this.mouseY; var axvel:int = mouseX - pmouseX; var ayvel:int = mouseY - pmouseY; mouseXvel = (axvel != mouseXvel) ? axvel : 0; mouseYvel = (ayvel != mouseYvel) ? ayvel : 0; for (var i:int = 0; i < lwidth; i++) { for (var u:int = 0; u < lheight; u++) { vbuf[i][u].updatebuf(i, u); v[i][u].col = 32; } } for (i = 0; i < pnum-1; i++) { p[i].updatepos(); } canvas.lock();//付け足し for (i = 0; i < lwidth; i++) { for (u = 0; u < lheight; u++) { v[i][u].addbuffer(i, u); v[i][u].updatevels(axvel, ayvel); v[i][u].display(i, u); } } canvas.unlock();//付け足し pmouseX = mouseX; pmouseY = mouseY; } private function mouseDownHandler(e:Event):void { mousePressed = true; } private function mouseUpHandler(e:Event):void { mousePressed = false; } } } import flash.display.BitmapData; var width:int = 400; var height:int = 400; var mousePressed:Boolean; var mouseX:Number = 0; var mouseY:Number = 0; var res:int = 5; var penSize:int = 50; var lwidth:int = 0; var lheight:int = 0; var pnum:int =10000; var v:Vector.<Vector.<vsquare>>; var vbuf:Vector.<Vector.<vbuffer>>; var p:Vector.<particle> = new Vector.<particle>(pnum, true); var pcount:int = 0; var mouseXvel:int = 0; var mouseYvel:int = 0; var canvas:BitmapData = new BitmapData(width, height, false, 0x0); class particle{ public function particle(xIn:Number, yIn:Number) { x = xIn; y = yIn; } public var x:Number = 0; public var y:Number = 0; public var xvel:Number = 0; public var yvel:Number = 0; public var pos:int = 0; public function updatepos():void { var col1:Number; if (x > 0 && x < width && y > 0 && y < height) { var vi:int = int(x / res); var vu:int = int(y / res); var o:vsquare = v[vi][vu]; var ax:Number = (x % res) / res; var ay:Number = (y % res) / res; xvel += (1 - ax) * v[vi][vu].xvel * 0.05; yvel += (1 - ay) * v[vi][vu].yvel * 0.05; xvel += ax * v[vi + 1][vu].xvel * 0.05; yvel += ax * v[vi + 1][vu].yvel * 0.05; xvel += ay * v[vi][vu + 1].xvel * 0.05; yvel += ay * v[vi][vu + 1].yvel * 0.05; o.col += 4; x += xvel; y += yvel; } else { x = Math.random() * width; y = Math.random() * height; xvel = 0; yvel = 0; } xvel *= 0.5; yvel *= 0.5; } } class vbuffer{ public function vbuffer(xIn:int, yIn:int) { x = xIn; y = yIn; pressurex = 0; pressurey = 0; } public var x:int = 0; public var y:int = 0; public var xvel:Number = 0; public var yvel:Number = 0; public var pressurex:Number = 0; public var pressurey:Number = 0; public var pressure:Number = 0; public function updatebuf(i:int, u:int):void { if (i > 0 && i < lwidth && u > 0 && u < lheight) { pressurex = (v[i - 1][u - 1].xvel * 0.5 + v[i - 1][u].xvel + v[i - 1][u + 1].xvel * 0.5 - v[i + 1][u - 1].xvel * 0.5 - v[i + 1][u].xvel - v[i + 1][u + 1].xvel * 0.5); pressurey = (v[i - 1][u - 1].yvel * 0.5 + v[i][u - 1].yvel + v[i + 1][u - 1].yvel * 0.5 - v[i - 1][u + 1].yvel * 0.5 - v[i][u + 1].yvel - v[i + 1][u + 1].yvel * 0.5); pressure = (pressurex + pressurey) * 0.25; } } } import flash.geom.Rectangle; class vsquare{ public function vsquare(xIn:int, yIn:int) { x = xIn; y = yIn; } public var x:int = 0; public var y:int = 0; public var xvel:Number = 0; public var yvel:Number = 0; public var col:Number = 0; public function addbuffer(i:int, u:int):void { if (i > 0 && i < lwidth && u > 0 && u < lheight) { xvel += (vbuf[i - 1][u - 1].pressure * 0.5 +vbuf[i - 1][u].pressure +vbuf[i - 1][u + 1].pressure * 0.5 -vbuf[i + 1][u - 1].pressure * 0.5 -vbuf[i + 1][u].pressure -vbuf[i + 1][u + 1].pressure * 0.5 ) * 0.25; yvel += (vbuf[i - 1][u - 1].pressure * 0.5 +vbuf[i][u - 1].pressure +vbuf[i + 1][u - 1].pressure * 0.5 -vbuf[i - 1][u + 1].pressure * 0.5 -vbuf[i][u + 1].pressure -vbuf[i + 1][u + 1].pressure * 0.5 ) * 0.25; } } public function updatevels(mvelX:int, mvelY:int):void { if (mousePressed) { var adj:Number = x - mouseX; var opp:Number = y - mouseY; var dist:Number = Math.sqrt(opp * opp + adj * adj); if (dist < penSize) { if (dist < 4) dist = penSize; var mod:Number = penSize / dist; xvel += mvelX * mod; yvel += mvelY * mod; } } xvel *= 0.99; yvel *= 0.99; } public function display(i:int, u:int):void { var tcol:Number = 0; if (col > 255) col = 255; if (i > 0 && i < lwidth - 1 && u > 0 && u < lheight - 1) { tcol = ( v[i][u + 1].col + v[i + 1][u].col + v[i + 1][u + 1].col * 0.5 ) * 0.4; tcol = int(tcol + col * 0.5); } else { tcol = int(col); } var coler:uint = tcol << 16 | tcol << 8 | tcol; canvas.fillRect(new Rectangle(x, y, res, res), coler); } } forked from: Processingの流体サンプル