flash on 2011-2-17

by kaaad
...
@author 啄木鳥@cybridge.jp
♥0 | Line 149 | Modified 2011-02-21 10:27:39 | MIT License
play

ActionScript3 source code

/**
 * Copyright kaaad ( http://wonderfl.net/user/kaaad )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/rA6u
 */

    package 
    {
        import flash.display.*;
        import flash.events.*;
        import flash.geom.*;
        import flash.utils.Timer;

        [SWF(backgroundColor="#3333cc", frameRate="60",width="128",height="128" )]
       
      
        public class Main extends Sprite 
        {
            public const SIZE:Number = 128;
            public var screen:BitmapData;

            public var CloudData:Array;        // 濃度
            public var CloudDataD:Array;    // 乱数テーブル
            
            public function Main():void 
            {
                if (stage) init();
                else addEventListener(Event.ADDED_TO_STAGE, init);
            }
            
            private function init(e:Event = null):void 
            {
                removeEventListener(Event.ADDED_TO_STAGE, init);
                // entry point
                
                // 背景色との加算合成
                this.blendMode = BlendMode.ADD;

                // BitmasDataの初期化
                screen = new BitmapData( stage.stageWidth, stage.stageHeight, true, 0xFFFFFFFF );
                addChild( new Bitmap( screen ) );

                // 雲データの初期化 
                initCloud();

                // 描画
                renderCloudData();
            }
            
            private function initCloud():void {
                
                // 配列の確保+乱数テーブルの作成
                CloudData = new Array(SIZE + 1);
                CloudDataD = new Array(SIZE + 1);
                
                var i:int;
                var j:int;
                for (i = 0; i < SIZE + 1;++i)
                {
                    CloudData[i] = new Array(SIZE + 1);
                    CloudDataD[i] = new Array(SIZE + 1);
                    
                    for (j = 0; j < SIZE + 1;++j) {
                        CloudDataD[i][j] = (Math.random()*2-1.0);
                    }
                }
                
                // 乱数テーブルから雲データの作成
                updateCloud();
            }
            
            private function updateCloud():void{

                // 初期の4点を求める
                
                CloudData[0][0] = CloudDataD[0][0] * SIZE ;
                CloudData[0][SIZE] = CloudDataD[0][SIZE] * SIZE ;
                CloudData[SIZE][0] = CloudDataD[SIZE][0] * SIZE ;
                CloudData[SIZE][SIZE] = CloudDataD[SIZE][SIZE] * SIZE ;
                
                // 再帰処理で残りの点を求める
                updateCloud_r(SIZE / 2);
            }
            
            private function updateCloud_r(level:int):void {

                // 再帰処理脱出
                if (level == 0)
                {
                    return;
                }
                
                var i:int;
                var j:int;

                // 前に計算した4点の中間点を求める
                for (i = level; i < SIZE; i += level*2 )
                {
                    for (j = level; j < SIZE; j += level*2 ) {
                        CloudData[i][j] = (CloudData[i - level][j - level] + CloudData[i - level][j + level] + CloudData[i + level][j - level] + CloudData[i + level][j + level]) / 4 + (CloudDataD[i][j] * level);
                    }
                }
                
                // 前に計算した2点と↑で計算した2点から中間点を求める
                var count:int;
                var c:Number;

                for (i = level; i < SIZE; i += level * 2 ) {
                    for (j = 0; j < SIZE + 1; j += level * 2 )
                    {
                        count = 0;
                        c = 0;
                        if (checkPoint(i - level, j)) {
                            ++count;
                            c += CloudData[i - level][ j];
                        }

                        if (checkPoint(i + level, j)) {
                            ++count;
                            c += CloudData[i + level][ j];
                        }

                        if (checkPoint(i, j - level)) {
                            ++count;
                            c += CloudData[i][ j - level];
                        }

                        if (checkPoint(i, j + level)) {
                            ++count;
                            c += CloudData[i][ j + level];
                        }
                        
                        CloudData[i][j] = c / count + (CloudDataD[i][j] * level);
                    }
                }
                
                for (i = 0; i < SIZE + 1 ; i += level * 2 )
                    for (j = level; j < SIZE; j += level * 2 ) {
                    {
                        count = 0;
                        c = 0;

                        if (checkPoint(i - level, j)) {
                            ++count;
                            c += CloudData[i - level][ j];
                        }

                        if (checkPoint(i + level, j)) {
                            ++count;
                            c += CloudData[i + level][ j];
                        }

                        if (checkPoint(i, j - level)) {
                            ++count;
                            c += CloudData[i][ j - level];
                        }

                        if (checkPoint(i, j + level)) {
                            ++count;
                            c += CloudData[i][ j + level];
                        }
                        
                        CloudData[i][j] = c / count+ (CloudDataD[i][j]*level);
                    }
                }
                
                // 再帰呼び出し
                updateCloud_r(level / 2);
            }
            
            // 座標が適切かどうか調べる
            private function checkPoint(i:int, j:int):Boolean
            {
                if (0 <= i && i < SIZE + 1 && 0 <= j && j < SIZE + 1) {
                    return true;
                }
                
                return false;
            }
            
            // レンダリング
            private function renderCloudData():void
            {
                var i:int;
                var j:int;
                var c:int;
                var c_max:Number;
                var c_min:Number;
                var d:Number;

                c_max = CloudData[0][0];
                c_min = -CloudData[0][0];

                
                for (i = 0; i < SIZE;++i) {
                    for (j = 0; j < SIZE;++j ) {
                        c_max = Math.max(c_max, CloudData[i][j]);
                        c_min = Math.min(c_min, CloudData[i][j]);
                    }
                }
                
                d = c_max - c_min;

                screen.lock();
                
                for (i = 0; i < SIZE;++i) {
                    for (j = 0; j < SIZE;++j ) {
                        c = 255 * (CloudData[i][j] - c_min) / d;
                        screen.setPixel32(i, j, (0xff000000 | (c<<16) | (c<<8) | c ));
                    }
                }
                
                screen.unlock();
                
            }
        }
        
    }