In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

波紋+環境マップ

波紋+環境マップ
マウスカーソルの位置に波が起きる
/**
 * Copyright Nao_u ( http://wonderfl.net/user/Nao_u )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/sabs
 */

// forked from Nao_u's テクスチャ生成実験
//   
// 波紋+環境マップ
//
// マウスカーソルの位置に波が起きる
//
package {      
    import flash.display.Sprite;      
    import flash.events.*;      
    [SWF(width="465", height="465", backgroundColor="0xFFFFFF", frameRate="60")] 
         
    public class FlashTest extends Sprite {      
        public function FlashTest() {      
            Main = this;      
            startLoad();     
            stage.addEventListener(Event.ENTER_FRAME,update);       
        }      
    }      
}          
import flash.display.*;  
import flash.events.* 
import flash.text.TextField;      
import flash.geom.*; 
import flash.utils.getTimer; 
import flash.ui.Keyboard; 
import flash.net.*;  

var Main:Sprite;      
var SCREEN_W:Number = 465; 
var SCREEN_H:Number = 465; 
var Text:TextField     

var Tex:ProcTex; 
var BITMAP_W:int = 465/2; 
var BITMAP_H:int = 465/2; 
var TexData: BitmapData;  
var loaderA:Loader;  
var loaderB:Loader;  
var bLoad:Boolean = false; 
         
function startLoad():void{      
    loaderA = new Loader();  
     loaderA.load( new URLRequest("http://img.f.hatena.ne.jp/images/fotolife/N/Nao_u/20090913/20091231171735.jpg") );  
    loaderA.contentLoaderInfo.addEventListener( Event.COMPLETE, loadComplete );  
} 

function loadComplete(e:Event):void {  
    loaderB = new Loader();  
    loaderB.contentLoaderInfo.addEventListener(Event.INIT, initialize);  
    loaderB.loadBytes(loaderA.contentLoaderInfo.bytes);  
} 

function initialize(event:Event):void {  
   var loader:Loader = loaderB; 
   TexData = new BitmapData(loader.width, loader.height, false);  
   TexData.draw(loader); 

    Tex = new ProcTex( BITMAP_W, BITMAP_H ); 
    Tex.Bmp.x = 0; 
    Tex.Bmp.y = 0; 

   Text = new TextField();      
   Text.text = "----";    
   Text.autoSize = "left"; 
   Main.addChild(Text);       
   bLoad = true; 
}  

// 更新
var mxPrev:int; 
var myPrev:int; 
var Pow:Number = 1.0; 
function update(e :Event):void{      
    var time:int = getTimer();  
        
    Tex.draw(); 
    var mx:int = Main.mouseX * BITMAP_W / SCREEN_W; 
    var my:int = Main.mouseY * BITMAP_H / SCREEN_H; 
    Pow += Math.abs(mx - mxPrev) + Math.abs(my - myPrev);
    if( Pow > 1.0 ) Pow = 1.0;
    Tex.addPower( mx, my, Pow );
    Pow *= 0.5;
    mxPrev = mx;
    myPrev = my;

    var endTime:int = getTimer() - time; 
    Text.text = " 生成時間:" + endTime + "[ms]";    
}   

// テクスチャ生成クラス
class ProcTex{ 
    public var BmpData:BitmapData;  
    public var TmpBmpData:BitmapData;  
    public var Bmp:Bitmap; 
    public var Width:int; 
    public var Height:int; 
    public var HeightBuf:Array;  
    public var HeightIdxDst:int;
    public var HeightIdxSrc0:int;
    public var HeightIdxSrc1:int;
    public var BufWidth:int; 
    public var BufHeight:int; 
        
    public var PixelBufSize:int = 256;  
    public var PixelBuf:Vector.<int>;  

    public function ProcTex( w:int, h:int ){ 
        Width = w; 
        Height = h; 
        BmpData = new BitmapData(Width, Height, false, 0xffffff);  
        Bmp = new Bitmap(BmpData);  
        Bmp.scaleX = 2.0; 
        Bmp.scaleY = 2.0; 
        Main.addChild(Bmp);       

        // 波高バッファの生成
         HeightBuf = new Array;  
        BufWidth = Width+2;
        BufHeight = Height+2;
        HeightBuf[0] = new Vector.<Number>;
        HeightBuf[1] = new Vector.<Number>;
        HeightBuf[2] = new Vector.<Number>;
        for( var x:int=-1; x<Width+1; x++ ){  
            for( var y:int=-1; y<Height+1; y++ ){
                var idx:int = (x+1) + (y+1)*BufWidth;
                HeightBuf[0].push( 0 );
                HeightBuf[1].push( 0 );
                HeightBuf[2].push( 0 );
            }
        }

        // 環境マップテクスチャバッファの生成
        PixelBuf = new Vector.<int>;
        for( x=0; x<PixelBufSize; x++ ){  
            for( y=0; y<PixelBufSize; y++ ){
                var col:int = TexData.getPixel(x, y);  
                PixelBuf.push(col);
            }
        }

        HeightIdxSrc0=0;
        HeightIdxSrc1=1;
        HeightIdxDst=2;
    } 

    public function draw():void{ 
        HeightIdxSrc0++;
        HeightIdxSrc1++;
        HeightIdxDst++;
        if( HeightIdxSrc0 > 2 ) HeightIdxSrc0 = 0;
        if( HeightIdxSrc1 > 2 ) HeightIdxSrc1 = 0;
        if( HeightIdxDst  > 2 ) HeightIdxDst  = 0;

        calcWave();     
        createBmp( HeightIdxDst );     
    }

    // 水面に力を加える
    public function addPower( px:int, py:int, pow:Number ):void{ 
        var r:int = 6;
        var buf:Vector.<Number> = HeightBuf[HeightIdxDst];
        for( var lx:int=-r; lx<=r; lx++ ){  
            for( var ly:int=-r; ly<=r; ly++ ){
                const d:Number = Math.sqrt(lx*lx+ly*ly); 
                if (d < r) { 
                    var p:Number = Math.cos(Math.PI/2 * d/r); 
                    var x:int = px + lx;  
                    var y:int = py + ly;  
                    if( x < 0 || x >= Width || y < 0 || y >= Height ) break;
                    var idx:int = (x+1) + (y+1)*BufWidth;
                    buf[idx] += pow * p;
                } 
            }
        }
    }

    // 水面画像の生成
    public function createBmp( idx:int ):void{ 
        var buf:Vector.<Number> = HeightBuf[HeightIdxDst];
        var col:Number, colU:Number, colL:Number, vecX:Number, vecY:Number; 
        var idx:int, ix:int, iy:int;
        BmpData.lock();
        for( var x:int=0; x<Width; x++ ){  
            for( var y:int=0; y<Height; y++ ){
                idx = (x+1) + (y+1)*BufWidth;
                col = buf[idx];
                colU = buf[idx-BufWidth];
                colL = buf[idx-1];
                vecX = ((colL - col)*0.55 + 1.0) *128; 
                vecY = ((colU - col)*0.55 + 1.0) *128;
                ix = vecX; iy = vecY;
                if( ix < 50 ) ix=50;
                if( iy < 50 ) iy=50;
                if( ix > 200 ) ix=200;
                if( iy > 200 ) iy=200;
                BmpData.setPixel(x, y, PixelBuf[ix+iy*PixelBufSize]);  
            }
        }    
        BmpData.unlock();
    }

    // 波計算
    public function calcWave():void{ 
        var c1:Number = 0.50;
        var c2:Number = 0.010;
        var cc:Number = 1 / (1 + c2);
        var srcBuf0:Vector.<Number> = HeightBuf[HeightIdxSrc0];
        var srcBuf1:Vector.<Number> = HeightBuf[HeightIdxSrc1];
        var dstBuf:Vector.<Number> = HeightBuf[HeightIdxDst];
        var idx:int, idxU:int, idxD:int, idxL:int, idxR:int;
        for( var x:int=0; x<Width; x++ ){  
            for( var y:int=0; y<Height; y++ ){
                idx  = (x+1) + (y+1)*BufWidth;
                idxU = (x+1) + (y  )*BufWidth;
                idxD = (x+1) + (y+2)*BufWidth;
                idxL = (x  ) + (y+1)*BufWidth;
                idxR = (x+2) + (y+1)*BufWidth;
                dstBuf[idx] = ( srcBuf1[idx] *(2-4*c1)  -srcBuf0[idx] * (1-c2) + 
                              ( srcBuf1[idxU] + srcBuf1[idxD] + srcBuf1[idxL] + srcBuf1[idxR]) * c1 ) * cc;
            }
        }    
    } 
}