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

forked from: QuickBox2Dで万華鏡

kaleidoscope
* 万華鏡(2)
* 
* 綺麗にしてみたつもり。
* 具は毎回ランダム。
/**
 * Copyright takishiki ( http://wonderfl.net/user/takishiki )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/oa2G
 */

// forked from takishiki's QuickBox2Dで万華鏡
/*
 * kaleidoscope
 * 万華鏡(2)
 * 
 * 綺麗にしてみたつもり。
 * 具は毎回ランダム。
 */

package 
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.display.MovieClip;
    import com.actionsnippet.qbox.*;
    import com.actionsnippet.qbox.QuickBox2D;
    import Box2D.Common.Math.b2Vec2;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.ColorTransform;
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.display.BlendMode;
    import flash.display.Graphics;
    import flash.filters.GlowFilter;
    
    
    [SWF(width=465, height=465, frameRate=30, backgroundColor=0xFFFFFF)]
    public class Main extends MovieClip 
    {
        // 定数
        private const QB2D_SCALE    :Number = 1 / 30;    // QuickBox2Dのスケール
        private const POLY_R        :int = 50;
        private const NUM            :int = 20;    // 具の数
        private const DEBUG            :Boolean = false;    // デバッグオフ
        private const GRAVITY        :int = 20;    // 重力
        // 変数
        private var _sp:Sprite;
        private var _bmp:Bitmap;
        private var _bmpd:BitmapData;
        private var _sim:QuickBox2D;
        private var _deg:Number = 0;
        private var _bgSp:Sprite;
        
        // constructor
        public function Main():void {
            stage.frameRate = 60;
            
            // 黒背景
            _bgSp = new Sprite();
            var g:Graphics = _bgSp.graphics;
            g.lineStyle();
            g.beginFill(0x000000, 1.0);
            g.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
            g.endFill();
            this.addChild(_bgSp);
            
            _sim = new QuickBox2D(this, { debug:DEBUG } );
            _sim.setDefault( { fillColor:0x000000, lineAlpha:0, radius:1.5 } );
            //_sim.createStageWalls();
            _sim.gravity = new b2Vec2(0, 0);    // 重力なし
            
            // 壁を配置
            var a:Number = stage.stageWidth / 4 * QB2D_SCALE;
            _sim.addBox( { x:a, y:a * 2, width:0.5, height:a * 2, angle:0, density:0, fillColor:0x000000 } );
            _sim.addBox( { x:a * 3, y:a * 2, width:0.5, height:a * 2, angle:0, density:0, fillColor:0x000000 } );
            _sim.addBox( { x:a * 2, y:a, width:a * 2, height:0.5, angle:0, density:0, fillColor:0x000000 } );
            _sim.addBox( { x:a * 2, y:a * 3, width:a * 2, height:0.5, angle:0, density:0, fillColor:0x000000 } );
            
            // 具を配置
            var type:int;
            var color:uint;
            var i:int;
            var obj:QuickObject;
            for (i = 0; i < NUM; i++) {
                type = randRange(0, 1);
                color = hsv2rgb(randRange(0, 359), 1, 1);
                if (type == 0) {
                    // 長方形
                    obj = _sim.addBox( {
                        x:stage.stageWidth / 2 * QB2D_SCALE, y:stage.stageHeight / 2 * QB2D_SCALE, 
                        width:randRange(1, 15) / 10, height:randRange(1, 15) / 10, 
                        fillColor:randRange(0, 1) * color, fillAlpha:1.0, 
                        lineColor:0, lineAlpha:0
                    } );
                    
                }else {
                    // 円
                    obj = _sim.addCircle( { 
                        x:stage.stageWidth / 2 * QB2D_SCALE, y:stage.stageHeight / 2 * QB2D_SCALE, 
                        radius:randRange(1, 6) / 10,
                        fillColor:randRange(0, 1) * color, fillAlpha:1.0, 
                        lineColor:0, lineAlpha:0
                    } );
                }
                // グローフィルター
                obj.userData.filters = [new GlowFilter(color, 0.8, 10, 10, 2, 2, true, false), new GlowFilter(color, 0.6, 20, 20, 4, 2, false, false),];
            }
            
            _sim.start();
            _sim.mouseDrag();
            
            
            var sp:Sprite = new Sprite();
            g = sp.graphics;
            g.beginFill(0x000000, 1.0);
            g.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
            drawPoly(sp, 3, stage.stageWidth / 2, stage.stageHeight / 2, POLY_R, 30);
            g.endFill();
            this.addChild(sp);
            
            _bmpd = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0x000000);
            _bmp = new Bitmap(_bmpd);
            _sp = new Sprite();
            _sp.addChild(_bmp);
            this.addChild(_sp);
            
            this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }
        
        // 多角形描画
        private function drawPoly(sp:Sprite, num:int, x:int, y:int, r:int, deg:Number):void {
            /*
             * sp:対象Sprite
             * num:頂点の数
             * x:中心のx座標
             * y:中心のy座標
             * r:半径
             * deg:回転角度(度)
             */
            var g:Graphics = sp.graphics;
            var rad:Number;
            var i:int;
            var step:Number = 360 / num;
            
            // 描画スタート位置に移動
            rad = deg2rad(0 + deg);
            g.moveTo(x + r * Math.cos(rad), y + r * Math.sin(rad));
            for (i = 0; i < num; i++) {
                rad = deg2rad((i + 1) * step + deg);
                g.lineTo(x + r * Math.cos(rad), y + r * Math.sin(rad));
            }
        }
        
        
        // フレーム処理
        private function onEnterFrame(event:Event):void {
            _deg += 1;
            if (_deg >= 360) {
                _deg -= 360;
            }
            var rad:Number = deg2rad(_deg);
            _sim.gravity = new b2Vec2(GRAVITY * Math.cos(rad), GRAVITY * Math.sin(rad));
            
            makeImage(_bmpd);
        }
        
        // 万華鏡画像作成
        private function makeImage(target:BitmapData):void {
            _sp.visible = false;
            
            var h:int = POLY_R * 3 / 2;
            var r3:Number = Math.sqrt(3);
            
            // ステージ用
            var bmpd:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight);
            // 元の三角形用
            var bmpdTri:BitmapData = new BitmapData(POLY_R * 2, POLY_R * 2, false, 0x000000);
            // 一行描画用
            var bmpdRow:BitmapData = new BitmapData(target.width, Math.ceil(h), false, 0x000000);
            
            // ステージ描画
            bmpd.lock();
            bmpd.draw(this);
            bmpd.unlock();
            
            var rect:Rectangle = new Rectangle();
            rect.x = Math.floor(stage.stageWidth / 2 - POLY_R);
            rect.y = Math.floor(stage.stageHeight / 2 - POLY_R);
            rect.width = POLY_R * 2;
            rect.height = POLY_R * 2;
            
            // 三角形部分を切り取り
            bmpdTri.copyPixels(bmpd, rect, new Point());
            
            var matrix:Matrix = new Matrix();
            var matrix2:Matrix = new Matrix();
            var rad:Number = Math.PI  * 2 / 3;    // 120°
            var num:int;
            var i:int;
            
            // 行作成
            bmpdRow.lock();
            num = Math.ceil(target.width / POLY_R) + 2;
            for (i = 0; i < num; i++) {
                matrix = new Matrix();
                
                // 中央に平行移動
                matrix2 = new Matrix();
                matrix2.translate( -POLY_R, -POLY_R);
                matrix.concat(matrix2);
                
                if (i % 2 == 0) {
                    // 偶数
                    
                    // 回転
                    matrix2 = new Matrix();
                    matrix2.rotate(-rad * i);
                    matrix.concat(matrix2);
                    
                }else {
                    // 奇数
                    
                    // 反転
                    matrix2 = new Matrix();
                    matrix2.scale(1, -1);
                    matrix.concat(matrix2);
                    
                    // 回転
                    matrix2 = new Matrix();
                    matrix2.rotate(-rad * int(i / 2) + rad);
                    matrix.concat(matrix2);
                    
                    // y軸平行移動
                    matrix2 = new Matrix();
                    matrix2.translate(0,  -POLY_R / 2);
                    matrix.concat(matrix2);
                }
                
                // x軸平行移動
                matrix2 = new Matrix();
                matrix2.translate(Math.floor(i * POLY_R / 2 * r3), 0);
                matrix.concat(matrix2);
                
                // 基準位置まで平行移動
                matrix2 = new Matrix();
                matrix2.translate(0, POLY_R);
                matrix.concat(matrix2);
                
                // 描画
                bmpdRow.draw(bmpdTri, matrix, new ColorTransform(), BlendMode.LIGHTEN);
            }
            bmpdRow.unlock();
            
            
            // 行のbmpdを反転しながら列方向に描画
            target.lock();
            // 背景色で塗りつぶし
            target.fillRect(target.rect, 0x000000);
            
            num = Math.ceil(target.height / POLY_R);
            for (i = 0; i < num; i++) {
                matrix = new Matrix();
                
                // 中央に平行移動
                matrix2 = new Matrix();
                matrix2.translate(0, -Math.round(h / 2));
                matrix.concat(matrix2);
                
                if (i % 2 == 1) {
                    // 奇数
                    // 反転
                    matrix2 = new Matrix();
                    matrix2.scale(1, -1);
                    matrix.concat(matrix2);
                }
                
                // 平行移動
                matrix2 = new Matrix();
                matrix2.translate(0, Math.floor(h * i));
                matrix.concat(matrix2);
                
                // 基準位置まで平行移動
                matrix2 = new Matrix();
                matrix2.translate(0, Math.round(h / 2));
                matrix.concat(matrix2);
                
                // 描画
                target.draw(bmpdRow, matrix, new ColorTransform(), BlendMode.LIGHTEN);
            }
            target.unlock();
            
            bmpdTri.dispose();
            bmpdRow.dispose();
            
            _sp.visible = true;
        }
        
        // HSV -> RGB(uint)
        private function hsv2rgb(h:Number, s:Number, v:Number):uint {
            var r:Number = 0;
            var g:Number = 0;
            var b:Number = 0;
            
            if (s == 0) {
                r = g = b = v;
            }else {
                var hTemp:Number = (h + 360) % 360;
                hTemp /= 60;
                var i:Number = Math.floor(hTemp);   // 整数部
                var f:Number = hTemp - i;    // 小数部
                
                var p:Number = v * (1.0 - s);
                var q:Number = v * (1.0 - (s * f));
                var t:Number = v * (1.0 - (s * (1.0 - f)));
                
                switch(i) {
                    case 0:
                        r = v;
                        g = t;
                        b = p;
                        break;
                    case 1:
                        r = q;
                        g = v;
                        b = p;
                        break;
                    case 2:
                        r = p;
                        g = v;
                        b = t;
                        break;
                    case 3:
                        r = p;
                        g = q;
                        b = v;
                        break;
                    case 4:
                        r = t;
                        g = p;
                        b = v;
                        break;
                    case 5:
                        r = v;
                        g = p;
                        b = q;
                        break;
                }
            }
            return rgb2hex(r * 255, g * 255, b * 255);
        }
        
        // R, G, B -> hex color value
        private function rgb2hex(r:Number = 0, g:Number = 0, b:Number = 0):uint {
            r = Math.round(r);
            g = Math.round(g);
            b = Math.round(b);
            return 0xff000000 + r * 0x10000 + g * 0x100 + b;
        }
        
        // degree -> radian
        private function deg2rad(deg:Number):Number {
            deg %= 360;
            return deg / 180 * Math.PI;
        }
        
        // a-bの乱数生成
        private function randRange(min:Number = 0, max:Number = 1):Number {
            var randomNum:Number = Math.floor(Math.random() * (max - min + 1)) + min;
            return randomNum;
        }
        
        
    }
    
}