[習作]Liquid10000

by ug24k8
nulldesignさんのLiquid10000 から連なるFork作品群を読みながら習作。
*
* マウスによる影響を追加。マウスの速度・ドットとの距離が影響
* Array を Vector に 変更
* 加速度マップの大きさを縮小
* 
♥0 | Line 108 | Modified 2010-06-16 14:18:27 | MIT License
play

ActionScript3 source code

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

/*
 * nulldesignさんのLiquid10000 から連なるFork作品群を読みながら習作。
 *
 * マウスによる影響を追加。マウスの速度・ドットとの距離が影響
 * Array を Vector に 変更
 * 加速度マップの大きさを縮小
 * */

package
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.BitmapDataChannel;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.geom.ColorTransform;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import net.hires.debug.Stats;

    [SWF(width="465", height="465", backgroundColor="0x000010", frameRate="60")]

    public class Main extends Sprite {
        private const DOT_NUM:uint = 10000;
        private const ACC_RATE:Number = 0.001;           // フォースマップの色→加速度変換率
        private const VEL_DEG_RATE:Number = 0.995;       // 速度の減衰率
        private const NOISE_OCT:uint = 4;                // フォースマップの複雑さ
        private const FORCEMAP_SCALE:uint = 50;          // フォースマップのドット率
        private const MOUSE_REPULSE_RATE:Number = 0.9;   // マウス斥力

        private var canvas:BitmapData = new BitmapData(350, 200, false, 0x000000);
        private var canvas_bmp:Bitmap = new Bitmap(canvas);
        private var accelerationData:BitmapData = new BitmapData(
                        canvas.width/FORCEMAP_SCALE, canvas.height/FORCEMAP_SCALE, false, 0x000000);
        private var dotList:Vector.<VectorDat> = new Vector.<VectorDat>(DOT_NUM, true);	// 個数固定
        private var blur_out:ColorTransform;
        private var lastMouse:Point = new Point();

        public function Main() {
            var i:int;

            // accelerationDataにノイズを加える。
            // このノイズのR値がX方向の加速度、G値がY方向の加速度をさす
            accelerationData.perlinNoise(accelerationData.width/2, accelerationData.height/2, NOISE_OCT,
                                Math.floor(Math.random() * 0xFFFFFFFF), false, true,
                                BitmapDataChannel.RED | BitmapDataChannel.GREEN);

            // ランダムな点を必要分設定。速度・加速度は0
            for (i = 0; i < DOT_NUM; ++i) {
                var px:Number = Math.random() * canvas.width;
                var py:Number = Math.random() * canvas.height;

                dotList[i] = new VectorDat(new Point(px, py));
            }

            // 簡易ブラーとして色変換値を設定
            blur_out = new ColorTransform(0.1, 0.9, 0.2, 0.9);

            // canvasを貼り付ける
            canvas_bmp.x = stage.stageWidth - canvas_bmp.width;
            addChild(canvas_bmp);

            // 加速度マップも貼り付けてみる
            var acceleration_bmp:Bitmap = new Bitmap(accelerationData);
            acceleration_bmp.x = canvas_bmp.x;
            acceleration_bmp.y = canvas_bmp.y + canvas_bmp.height;
            acceleration_bmp.scaleX = acceleration_bmp.scaleY = FORCEMAP_SCALE;
            addChild(acceleration_bmp);

            // 状態チェッカーも貼り付けてみる
            addChild(new Stats());

            // 毎フレーム処理登録
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }

        // 毎フレーム処理
        private function onEnterFrame(evt:Event):void {
            canvas.lock();
            // ブラーなし
 //           canvas.fillRect(new Rectangle(0, 0, canvas.width, canvas.height), 0x000000);
            // 簡易ブラー
            canvas.colorTransform(canvas.rect, blur_out);

            // マウス移動速度
            var speed:Number = Point.distance(
                                    lastMouse, 
                                    new Point(canvas_bmp.mouseX, canvas_bmp.mouseY));

            // ループの回数を考慮してアクセスを減らす
            var canvas_width:int = canvas.width;
            var canvas_height:int = canvas.height;

            for (var i:int = 0; i < DOT_NUM; ++i) {
                var dot:VectorDat = dotList[i];
                var acc_col:uint = accelerationData.getPixel(
                                    dot.position.x/FORCEMAP_SCALE, 
                                    dot.position.y/FORCEMAP_SCALE);
                var acc_x:Number = (((acc_col >> 16) & 0xFF) - 0x80) * ACC_RATE;
                var acc_y:Number = (((acc_col >>  8) & 0xFF) - 0x80) * ACC_RATE;
                // 速度の減衰
                dot.velocity.x *= VEL_DEG_RATE;
                dot.velocity.y *= VEL_DEG_RATE;
                // 速度に加速度追加
                dot.velocity.x += acc_x;
                dot.velocity.y += acc_y;
                // 距離を調べる
                var dot_diff_x:int = dot.position.x - canvas_bmp.mouseX;
                var dot_diff_y:int = dot.position.y - canvas_bmp.mouseY;
                var dot_diff_pow:int = (dot_diff_x * dot_diff_x) + (dot_diff_y * dot_diff_y);
                if (dot_diff_pow > 0) {
                    dot.velocity.x += speed * dot_diff_x / dot_diff_pow * MOUSE_REPULSE_RATE;
                    dot.velocity.y += speed * dot_diff_y / dot_diff_pow * MOUSE_REPULSE_RATE;;
                }
                // ポイントの位置を更新
                dot.position.x += dot.velocity.x;
                dot.position.y += dot.velocity.y;

                // はみ出ないように調整
                if (dot.position.x < 0) {
                    dot.position.x = 0;
                    dot.velocity.x *= -1;
                }
                else if (dot.position.x > canvas_width) {
                    dot.position.x = canvas_width;
                    dot.velocity.x *= -1;
                }

                if (dot.position.y < 0) {
                    dot.position.y = 0;
                    dot.velocity.y *= -1;
                }
                else if (dot.position.y > canvas_height) {
                    dot.position.y = canvas_height;
                    dot.velocity.y *= -1;
                }

                // 描画
                canvas.setPixel(dot.position.x, dot.position.y, 0xFFFFFFFF);
//                canvas.fillRect(new Rectangle(dot.position.x, dot.position.y, 1, 1), 0xFFFFFF);
            }
            canvas.unlock();
            lastMouse.x = canvas_bmp.mouseX;
            lastMouse.y = canvas_bmp.mouseY;
        }
    }
}

import flash.geom.Point;
class VectorDat {
    public var velocity:Point;
    public var position:Point;

    function VectorDat(_pv:Point) {
        velocity = new Point();
        position = _pv;
    }
}