Forked from: wanson's Water Pool diff:274 水面。画像がゆがむはずだが・・・ 水面を作成する。 @author SIBA siba2260 forked:6favorite:3lines:137license : All rights reserved modified : 2009-01-29 23:39:51 Embed Tweet package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.BitmapDataChannel; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.filters.DisplacementMapFilter; import flash.filters.DisplacementMapFilterMode; import flash.geom.Matrix; import flash.geom.Point; import flash.display.Loader; import flash.display.LoaderInfo; import flash.system.LoaderContext; import flash.system.Security; import flash.net.URLRequest; [SWF(width=800, height=600, backgroundColor=0xAADDFF)] /** * 水面を作成する。 * @author SIBA */ public class Main03 extends Sprite { // ---------------------------- // 定数 // ---------------------------- private const C1:Number = 0.5; private const C2:Number = 0.005; private const CC:Number = 1 / (1 + C2); private const SCALE:int = 10; private const FIELD_SIZE_X:int = 800 / SCALE + 2; private const FIELD_SIZE_Y:int = 600 / SCALE + 2; // ---------------------------- // メンバ変数 // ---------------------------- private var map:Bitmap; // 水面の画像 private var bitmapData:BitmapData; // 水面のデータ private var field1:Array = []; // 前回の水面データ private var field2:Array = []; // 現在の水面データ private var dmf:DisplacementMapFilter; // 水面のゆがみを作るFilter private var woterLayer:Sprite = new Sprite(); // 水面のレイヤ private var objectLayer:Sprite = new Sprite(); // オブジェクトのレイヤ // ---------------------------- // 初期化 // ---------------------------- public function Main03() { // レイヤーの配置 addChild(objectLayer); addChild(woterLayer); objectLayer.graphics.drawRect(0, 0, 800, 600); // 水面の揺らぎを作るためのFilterを作成 var channel:int = BitmapDataChannel.ALPHA; dmf = new DisplacementMapFilter(null, new Point(), channel, channel, 50, 50, DisplacementMapFilterMode.COLOR) // 画像の配置 Security.loadPolicyFile("http://farm2.static.flickr.com/crossdomain.xml"); var context:LoaderContext = new LoaderContext(true); var loader:Loader = new Loader(); loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete); loader.load(new URLRequest("http://farm4.static.flickr.com/3180/3115974098_d1b27674ef.jpg?v=0"), context); // 水面を表示するための画像を作成 bitmapData = new BitmapData(FIELD_SIZE_X, FIELD_SIZE_Y, true, 0xFFFFFFFF); map = new Bitmap(bitmapData); map.scaleX = SCALE; map.scaleY = SCALE; woterLayer.addChild(map); // フィールドの初期化 for (var i:int=0; i<FIELD_SIZE_X; i++) { field1[i] = []; field2[i] = []; for (var j:int=0; j<FIELD_SIZE_Y; j++) { field1[i][j] = 0.0; field2[i][j] = 0.0; } } } // ---------------------------- // 内部メソッド // ---------------------------- /** * 波を立てる。 * @param px 波を立てる位置(x座標) * @param py 波を立てる位置(y座標) * @param power */ private function put(px:Number, py:Number, power:Number):void { // 立てる波の情報 const r:uint = 5; const beginX:int = (px - r < 1) ? 1 : px - r; const endX:int = (px + r > FIELD_SIZE_X - 1) ? FIELD_SIZE_X - 1 : px + r; const beginY:int = (py - r < 1) ? 1 : py - r; const endY:int = (py + r > FIELD_SIZE_Y - 1) ? FIELD_SIZE_Y - 1 : py + r; // 波の起点を作成 for (var xx:int=beginX; xx<endX; xx++) { for (var yy:int=beginY; yy<endY; yy++) { const d:Number = Point.distance(new Point(px, py), new Point(xx, yy)); if (d < r) { var p:Number = power * Math.cos(Math.PI/2 * d/r); field1[xx][yy] += p; field2[xx][yy] += p; } } } } // ---------------------------- // イベント // ---------------------------- private function onComplete(event:Event):void { var loaderInfo:LoaderInfo = event.currentTarget as LoaderInfo; var loader:Loader = loaderInfo.loader; var bmp:BitmapData = new BitmapData(loader.width, loader.height, true, 0x00FFFFFF); bmp.draw(loader); var image:Bitmap = new Bitmap(bmp); image.x = 400 - image.width/2; image.y = 300 - image.height/2; objectLayer.addChild(image); addEventListener(Event.ENTER_FRAME, onEnterFrame); stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); } private function onMouseMove(event:MouseEvent):void { put(event.stageX/SCALE, event.stageY/SCALE, 15); } private function onEnterFrame(event:Event):void { // 初期化 var xx:int = 0; var yy:int = 0; // 波を描く bitmapData.lock(); for (xx=1; xx<FIELD_SIZE_X; xx++) { for (yy=1; yy<FIELD_SIZE_Y; yy++) { var c:uint = Math.abs(field2[xx][yy]); var a:uint = (c + 32 > 255) ? 255 : c + 32; var r:uint = (c + 128 > 255) ? 255 : c + 128; var g:uint = (c + 160 > 255) ? 255 : c + 160; var b:uint = (c + 192 > 255) ? 255 : c + 192; bitmapData.setPixel32(xx-1, yy-1, (a << 24) | (r << 16) | (g << 8) | b); } } bitmapData.unlock(); // 波の動きを計算 for (xx=1; xx<FIELD_SIZE_X-1; xx++) { for (yy=1; yy<FIELD_SIZE_Y-1; yy++) { field1[xx][yy] = (field2[xx][yy] * (2 - 4 * C1) - field1[xx][yy] * (1 - C2) + (field2[xx][yy+1] + field2[xx][yy-1] + field2[xx-1][yy] + field2[xx+1][yy]) * C1) * CC; } } // 次へ const temp:Array = field1; field1 = field2; field2 = temp; // 全体に水面エフェクト var tempBmp:BitmapData = new BitmapData(map.width, map.height, true, 0x00FFFFFF); var mat:Matrix = new Matrix(); mat.scale(map.scaleX, map.scaleY); tempBmp.draw(map, mat); dmf.mapBitmap = tempBmp objectLayer.filters = [dmf]; } } } Code Fullscreen Preview Fullscreen CLAPTAPS NaoHachi Giggle map DisplacementMapFilterMode.COLOR loader currentTarget addEventListener width height stageY stageX Point.distance Security.loadPolicyFile MouseEvent.MOUSE_MOVE MouseEvent.ENTER_FRAME Math.abs MouseEvent Math.PI Math.cos uint Point Array sort new page view favorite forked pv0 forked from: 水面。画像がゆがむはずだが・・・ tokigawatei forked:0 favorite:0lines:137 (diff:1) pv289 forked from: 水面。画像がゆがむはずだが・・・ _swim forked:0 favorite:0lines:136 (diff:3) pv320 forked from: 水面。画像がゆがむはずだが・・・ _swim forked:0 favorite:0lines:137 (diff:2) pv341 forked from: 水面。画像がゆがむはずだが・・・ _swim forked:0 favorite:0lines:137 (diff:2) pv609 forked from: 水面。画像がゆがむはずだが・・・ uwi forked:0 favorite:1lines:137 (diff:2) pv435 forked from: 水面。画像がゆがむはずだが・・・ hacker_6zt212pi forked:0 favorite:0lines:137 (diff:1)