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

グラデーション球のPerlinNoise変調で雲を描画

グラデーションのかかった球をマウスカーソル位置に従って、2枚のPerlinNoiseでUVを個別に変調
画面中央にマウスカーソルを持って行くと変調なしに

カーソルキーで移動速度を調整
Get Adobe Flash player
by Nao_u 12 Aug 2011
/**
 * 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/aDKY
 */

// forked from Nao_u's Water Flow 
// forked from Nao_u's 2D流体
// forked from Nao_u's 波紋+環境マップ
//   
// グラデーション球のPerlinNoise変調
// 
// マウスカーソル位置に従って変調
// 画面中央にマウスカーソルを持って行くと変調なしに
//
// カーソルキーで移動速度を調整
//
package {      
    import flash.display.Sprite;      
    import flash.events.*;      
    [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")] 
         
    public class FlashTest extends Sprite {      
        public function FlashTest() {      
            Main = this;      
            initialize();  

            stage.addEventListener(Event.ENTER_FRAME,update);       
            stage.addEventListener(KeyboardEvent.KEY_UP,   keyCheckUp); 
            stage.addEventListener(KeyboardEvent.KEY_DOWN, keyCheckDown); 
            stage.addEventListener(MouseEvent.MOUSE_UP,    MouseCheckUp);     
            stage.addEventListener(MouseEvent.MOUSE_DOWN,  MouseCheckDown);     

        }      
    }      
}          
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; 
function initialize():void {  

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

   Text = new TextField();      
   Text.text = "----";    
   Text.autoSize = "left"; 
   Text.textColor = 0xFFFFFF;
   Main.addChild(Text);       
}  

var g_Scale0:Number = 0.0;
var g_Scale1:Number = 0.0;
var g_AddX:Number = 0.0;
var g_AddY:Number = 0.0;
var g_SpdX:Number = 1.0;
var g_SpdY:Number = 1.0;
// 更新
function update(e :Event):void{      
    var time:int = getTimer();  
        
    graphicClear();   
    Tex.draw(); 
    var mx:int = Main.mouseX * BITMAP_W / SCREEN_W; 
    var my:int = Main.mouseY * BITMAP_H / SCREEN_H;
          
    if( KeyData & KEY_UP )    g_SpdY += 0.1;
    if( KeyData & KEY_DOWN )  g_SpdY -= 0.1;
    if( KeyData & KEY_LEFT )  g_SpdX += 0.1;
    if( KeyData & KEY_RIGHT ) g_SpdX -= 0.1;
    g_Scale0 = (mx - SCREEN_W/4)*0.005;
    g_Scale1 = (my - SCREEN_W/4)*0.005;
    g_AddX += g_SpdX;
    g_AddY += g_SpdY;
    
    var px:int = g_Scale0 * 200;
    var py:int = g_Scale1 * 200;
//  var endTime:int = getTimer() - time; 
    Text.text = "Px=" + px + " Py=" + py;  
    KeyPrev = KeyData;  
}   

// テクスチャ生成クラス
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 VelXBuf:Vector.<Number>;  
    public var VelYBuf:Vector.<Number>;  
    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);       

        BufWidth = Width+2;
        BufHeight = Height+2;
        
        // ノイズバッファの生成
         VelXBuf = new Vector.<Number>;  
         VelYBuf = 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;
                
                var fretX:Number = Noise2( x+256, y+256, 40, 0.4,4,false,0 );
                var fretY:Number = Noise2( x+256, y+256, 40, 0.4,4,false,50 );
                fretX *= 0.3;
                fretY *= 0.3;
                VelXBuf.push( fretX );
                VelYBuf.push( fretY );
            }
        }

        // ノイズバッファの縦横リピート処理
        var wd:int = 64;
        var r:Number;
        var ir:Number;
        for( x=0; x<wd; x++ ){
            r = x / wd;
            ir = 1 - r;
            for( y=0; y<Height; y++ ){                
                idx  = (x) + (y)*BufWidth;
                var idx2:int = (0x80+x) + (y)*BufWidth;
                VelXBuf[idx] = VelXBuf[idx]*r + VelXBuf[idx2]*ir;
                VelYBuf[idx] = VelYBuf[idx]*r + VelYBuf[idx2]*ir;
            }
        }        
        for( y=0; y<wd; y++ ){                
            r = y / wd;
            ir = 1 - r;
            for( x=0; x<Width; x++ ){
                idx  = (x) + (y)*BufWidth;
                idx2 = (x) + (0x80+y)*BufWidth;
                VelXBuf[idx] = VelXBuf[idx]*r + VelXBuf[idx2]*ir;
                VelYBuf[idx] = VelYBuf[idx]*r + VelYBuf[idx2]*ir;
            }
        }        
        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 getCircleTex( x:Number, y:Number ):int{
          x -= BufWidth/2;
          y -= BufWidth/2;
          var ret:int =  (256-3*Math.sqrt(x*x+y*y));
          if( ret < 0 ) ret = 0;
          return ret;
    }

    // 画像の生成
    public function createBmp( idx:int ):void{ 
        var col:Number, colU:Number, colL:Number;
        var vecX0:Number, vecY0:Number, vecX1:Number, vecY1:Number, vx:Number, vy:Number; 
        var ix:int, iy:int, idx0:int, idx1:int;
        BmpData.lock();
        for( var x:int=0; x<Width-10; x++ ){  
            for( var y:int=0; y<Height-10; y++ ){
                var px:int = x + g_AddX;
                var py:int = y + g_AddY;
                px = px&0x7f;
                py = py&0x7f;
                idx = (px+1) + (py+1)*BufWidth;
                vx = VelXBuf[idx];
                vy = VelYBuf[idx];
                vecX0 = vx * 1000.0 * g_Scale0;
                vecY0 = vy * 1000.0 * g_Scale1;
                
                var c:Number = getCircleTex(x/1.0-vecX0, y/1.0-vecY0);
                if( c >= 255 ) c = 255;
                BmpData.setPixel(x, y, c+c*256+c*65536); 
            }
        }    
        BmpData.unlock();
    }
}

function graphicClear():void{   
    Main.graphics.clear();    
}   
function Rand( min:Number, max:Number ):Number{
    return  Math.random() * (max-min) + min;
}




// PerlinNoiseを生成(通常)
function Noise2( x:Number, y:Number, frequency:Number, presistence:Number, octave:int, bAbs:Boolean, base:Number ):Number{
    var total:Number = 0;
    var amplitude:Number = presistence;
    
    for( var i:int=0; i<octave; i++ ){
        total += makeNoise( base+x, base+y, frequency, amplitude, bAbs );
        amplitude *= presistence;
        frequency *= 0.5;
    }
    return total;
}


// 周波数に対応したノイズを生成
function makeNoise( x:Number, y:Number, frequency:Number, amplitude:Number, bAbs:Boolean ):Number{
    if( bAbs ) return Math.abs(rndSmooth(x/frequency,y/frequency) * amplitude);
    else       return (rndSmooth(x/frequency,y/frequency) * amplitude);
}

// 入力値( x, y ) に対応した、滑らかな擬似乱数を生成 (補間の結果-1.0を下回ったり、1.0を超えることがある)
function rndSmooth( x:Number, y:Number ):Number{
    var tx:Number = (x - Math.floor(x));
    var txInv:Number = 1.0 - tx;
    var ty:Number = (y - Math.floor(y));
    var tyInv:Number = 1.0 - ty;
    var ix:int = x;
    var iy:int = y;

    // cos補間
    var x0:Number = interpolate( rnd(ix, iy),   rnd(ix+1, iy),   tx );
    var x1:Number = interpolate( rnd(ix, iy+1), rnd(ix+1, iy+1), tx );
    return interpolate( x0, x1, ty );
}

// a から b をcosでなめらかに補間
function interpolate( a:Number, b:Number, t:Number ):Number{
    var ft:Number = t * Math.PI;
    var f:Number = (1.0 - Math.cos( ft )) * 0.5;
    return a * (1.0 - f) + b * f;
}

// 入力値( x, y ) に対応した、-1.0 ~ 1.0 の擬似乱数を生成
function rnd( x:int, y:int ):Number{
    x += y * 465 + 789221;    // 465=2次元での横幅に対応
    x = (x>>10) ^ x;
    var ret:int = (( (x * (x * x * 15731 + 789221) + 1376312589) ) / 1000000);
    
    return ((((ret & 0xff) + ((ret & 0xff00)>>8)+ ((ret & 0xff0000)>>16))&0x1ff) / 256) - 1.0;
}

// マウス関連
var MOUSE_LEFT:int = 0x01;    
var MOUSE_LEFT_TRG:int = 0x02;    
var MouseData:int;    
function MouseCheckDown(event:MouseEvent):void{    
    MouseData |= MOUSE_LEFT;    
    MouseData |= MOUSE_LEFT_TRG;    
}             

function MouseCheckUp(event:MouseEvent):void{    
    MouseData &= ~MOUSE_LEFT;    
}             

function MouseUpdate():void{    
    MouseData &= ~MOUSE_LEFT_TRG;    
}  

// キーボード関連
var KEY_UP:int    = 0x01;
var KEY_DOWN:int  = 0x02;
var KEY_LEFT:int  = 0x04;
var KEY_RIGHT:int = 0x08;
var KEY_SPACE:int = 0x10;
var KeyData:int;
var KeyPrev:int;
function keyCheckDown(event:KeyboardEvent):void { 
    switch (event.keyCode){ 
        case Keyboard.UP:	    KeyData |= KEY_UP; break;
        case Keyboard.DOWN:	    KeyData |= KEY_DOWN; break;
        case Keyboard.LEFT:    KeyData |= KEY_LEFT; break;
        case Keyboard.RIGHT:   KeyData |= KEY_RIGHT; break;
        case Keyboard.SPACE:   KeyData |= KEY_SPACE; break;
    }
} 
function keyCheckUp(event:KeyboardEvent):void { 
    switch (event.keyCode){ 
        case Keyboard.UP:      KeyData &= ~KEY_UP; break;
        case Keyboard.DOWN:    KeyData &= ~KEY_DOWN; break;
        case Keyboard.LEFT:    KeyData &= ~KEY_LEFT; break;
        case Keyboard.RIGHT:   KeyData &= ~KEY_RIGHT; break;
        case Keyboard.SPACE:   KeyData &= ~KEY_SPACE; break;
    }
}