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: マルチタッチってこうですか!?  わかりません><

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

// forked from Aquioux's マルチタッチってこうですか!?  わかりません>< 
package {
    import flash.display.Sprite;
    import flash.events.Event;
    import net.hires.debug.Stats;
    /**
     * 注意! タイトルは釣りです!!!!
     * 言い訳(説明)は http://aquioux.blog48.fc2.com/blog-entry-651.html にて
     * @author YOSHIDA, Akio (Aquioux)
     */
    [SWF(width = "465", height = "465", frameRate = "60", backgroundColor = "#FFFFFF")]
    
    public class Main extends Sprite {
        
        public function Main() {
            // Model を生成
            var model:Model = new Model(stage);

            // View を生成
            var view:View = new View(model);
            addChild(view);
            
            // Controller を生成
            var controller:Controller = new Controller(model);
            controller.setup(stage);
            
            model.setData(15, 15, 31, 31);
        }
    }
}


    import flash.display.GraphicsEndFill;
    import flash.display.GraphicsPath;
    import flash.display.GraphicsPathCommand;
    import flash.display.GraphicsSolidFill;
    import flash.display.GraphicsStroke;
    import flash.display.IGraphicsData;
    import flash.display.Stage;
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.geom.Point;
    
    class Model extends EventDispatcher {
        // --------------------------------------------------
        // View へ渡すデータ(プロパティ)
        // --------------------------------------------------
        /**
         * GraphicsData Vector
         */
        public function get graphicsData():Vector.<IGraphicsData> { return _graphicsData; }
        private var _graphicsData:Vector.<IGraphicsData>;
        /**
         * 上記 GraphicsData Vector の第何番目の要素が GraphicsPath かを示すインデックス
         */
        public function get idx():uint { return _idx; }
        private var _idx:uint;
        /**
         * 上記 GraphicsData Vector の GraphicsPath の data プロパティ
         */
        public function get data():Vector.<Number> { return _data; }
        private var _data:Vector.<Number>;
        /**
         * Point の Vector(この各 Point をタッチしている点と見なす)
         */
        public function get touchPoints():Vector.<Point> { return _touchPoints; }
        private var _touchPoints:Vector.<Point> = Vector.<Point>([new Point(), new Point(), new Point()]);
        
        
        // --------------------------------------------------
        // データアクセサー(外部からデータを取得する)
        // --------------------------------------------------
        /**
         * アンカー座標数を取得するアクセサー
         * @param    segmentW    横方向のセグメント数
         * @param    segmentH    縦方向のセグメント数
         * @param    intervalW    横方向のセグメント長
         * @param    intervalH    縦方向のセグメント長
         */
        private var numOfVertex:uint;            // アンカー座標の数
        private var vertexs:Array;                // アンカー座標インスタンス格納配列(update 更新用)
        private var vertexsForDraw:Array;        // アンカー座標インスタンス格納配列(drawAPI 用)
        private var graphicsPath:GraphicsPath;    // GraphicsPath
        public function setData(segmentW:uint, segmentH:uint, intervalW:Number = 100.0, intervalH:Number = 100.0):void {
            numOfVertex = (segmentW + 1) * (segmentH + 1);
            
            var offsetX:Number = (stage.stageWidth  - segmentW * intervalW) / 2;
            var offsetY:Number = (stage.stageHeight - segmentH * intervalH) / 2;
            
            // 頂点の生成および格納
            vertexs = [];
            for (var i:int = 0; i <= segmentH; i++) {
                for (var j:int = 0; j <= segmentW; j++) {
                    var vertex:Coordinate = new Coordinate(j * intervalW + offsetX+Math.random()*16-8, i * intervalH + offsetY+Math.random()*16-8);
                    vertexs.push(vertex);
                }
            }
            vertexsForDraw = [];
            vertexsForDraw = vertexsForDraw.concat(vertexs);
            for (j = 0; j <= segmentW; j++) {
                for (i = 0; i <= segmentH; i++) {
                    var idx:uint = (segmentW + 1) * i + j;
                    vertexsForDraw.push(vertexs[idx]);
                }
            }
            
            // View へ渡すデータの初期化
            // GraphicsData の各要素
            // 線
            var stroke:GraphicsStroke = new GraphicsStroke(1);
            stroke.fill = new GraphicsSolidFill(0xCC0033);
            // GraphicsPath の commands プロパティ
            var commands:Vector.<int> = new Vector.<int>();
            for (i = 0; i <= segmentH; i++) {
                for (j = 0; j <= segmentW; j++) {
                    if (j == 0) {
                        commands.push(GraphicsPathCommand.MOVE_TO);
                    }
                    if (j < segmentW) {
                        commands.push(GraphicsPathCommand.LINE_TO);
                    }
                }
            }
            for (j = 0; j <= segmentW; j++) {
                for (i = 0; i <= segmentH; i++) {
                    if (i == 0) {
                        commands.push(GraphicsPathCommand.MOVE_TO);
                    }
                    if (i < segmentH) {
                        commands.push(GraphicsPathCommand.LINE_TO);
                    }
                }
            }
            
            // Graphicspath
            graphicsPath = new GraphicsPath(commands, coordinateToVector());
            
            // GraphicsData の調整
            _graphicsData = new Vector.<IGraphicsData>();
            _graphicsData.push(stroke);
            _graphicsData.push(graphicsPath);
            _graphicsData.push(new GraphicsEndFill());
            // インデックスの取得
            _idx = 1;
            
            dispatchEvent(new Event(Event.INIT));
        }
        
        
        // --------------------------------------------------
        // 外部との通信をおこなうメソッド
        // --------------------------------------------------
        /**
         * 対 View 用メソッド
         * このメソッドの終了時にイベントを発行するので、View との通信手段となる
         * @private
         */
        private function update():void {
            var nPoint:uint  = _touchPoints.length;
            var nVertex:uint = numOfVertex;
            for (var i:int = 0; i < nPoint; i++) {
                for (var j:int = 0; j < nVertex; j++) {
                    var v:Coordinate = vertexs[j];
                    v.update(_touchPoints[i]);
                }
            }
            _data = coordinateToVector();
            
            dispatchEvent(new Event(Event.CHANGE));
        }
        
        /**
         * 対 Controller 用メソッド
         * Controller から受け取りたい値が引数
         * @param    vector    ポイント座標の1次元 Vector
         */
        internal function updateFromController(vector:Vector.<Point>):void {
            _touchPoints = vector;
            update();
        }
        
        
        // --------------------------------------------------
        // その他のメソッド
        // --------------------------------------------------
        /**
         * 頂点の座標を1次元 Vector に格納する
         * @private
         */
        private function coordinateToVector():Vector.<Number> {
            var n:uint = numOfVertex * 2;
            var vector:Vector.<Number> = new Vector.<Number>(n * 2, true);
            for (var i:int = 0; i < n; i++) {
                var v:Coordinate = vertexsForDraw[i];
                vector[i * 2]     = v.x;
                vector[i * 2 + 1] = v.y;
            }
            return vector;
        }
        
        /**
         * コンストラクタ
         * コンストラクタの引数はステージとする。各種データはアクセサーによって取り込むものとする
         * @param    stage    ステージ
         */
        private var stage:Stage;
        public function Model(stage:Stage) {
            this.stage = stage;
        }
    }


    import caurina.transitions.Tweener;
    import flash.display.Stage;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.events.TimerEvent;
    import flash.geom.Point;
    import flash.utils.Timer;

    class Controller {
        /**
         * コンストラクタ
         * @param    model    Model
         */
        private var model:Model;
        public function Controller(model:Model) {
            this.model = model;
        }
        
        /**
         * このクラスのインスタンス生成後、最初に実行
         * ステージ参照を得て、イベントリスナーを登録する。Event.ENTER_FRAME を使いたい場合は Model で登録する。
         * Controller は MouseEvent や KeyboradEvent などが対象となる。
         * @param    stage    ステージ
         */
        private var stage:Stage;
        private var stageWidth:Number;
        private var stageHeight:Number;
        private var touch1:Vertex2D;
        private var touch2:Vertex2D;
        private var touchPoints:Vector.<Point>;
        public function setup(stage:Stage):void {
            this.stage  = stage;
            stageWidth  = stage.stageWidth;
            stageHeight = stage.stageHeight;
            
            touch1 = new Vertex2D(stageWidth / 2, stageHeight / 2);
            touch2 = new Vertex2D(stageWidth / 2, stageHeight / 2);
            touchPoints = Vector.<Point>([new Point(), new Point(), new Point()]);
            touchPoints.fixed = true;
            
            stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
            var timer:Timer = new Timer(2000);
            timer.addEventListener(TimerEvent.TIMER, timerHandler);
            timer.start();
        }
        private function timerHandler(event:TimerEvent):void {
            var w:Number = stageWidth;
            var h:Number = stageHeight;
            Tweener.addTween(touch1, { x:Math.random() * w, y:Math.random() * h, time:2 } );
            Tweener.addTween(touch2, { x:Math.random() * w, y:Math.random() * h, time:2 } );
        }
        
        /**
         * イベントハンドラ
         * Model との通信手段
         * @param    event    発生したイベント
         */
        private function enterFrameHandler(event:Event):void {
            touchPoints[0].x = stage.mouseX;
            touchPoints[0].y = stage.mouseY;
            touchPoints[1].x = touch1.x;
            touchPoints[1].y = touch1.y;
            touchPoints[2].x = touch2.x;
            touchPoints[2].y = touch2.y;
            model.updateFromController(touchPoints);
        }
    }


    import flash.display.GraphicsPath;
    import flash.display.IGraphicsData;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.geom.Point;

    class View extends Sprite {
        /**
         * コンストラクタ
         * @param    model    Model
         */
        private var model:Model;
        public function View(model:Model) {
            this.model = model;
            this.model.addEventListener(Event.INIT, initHandler);
            this.model.addEventListener(Event.CHANGE, changeHandler);
        }
        
        /**
         * Model との通信手段
         * @param    event    発生したイベント
         */
        private var    graphicsData:Vector.<IGraphicsData>;
        private var idx:uint;
        // INIT
        private function initHandler(event:Event):void {
            removeEventListener(Event.INIT, initHandler);
            // Model からデータを受け取る
            graphicsData = model.graphicsData;
            idx          = model.idx;
        }
        // ENTER_FRAME
        private function changeHandler(event:Event):void {
            // Model からデータを受け取る
            GraphicsPath(graphicsData[idx]).data = model.data;
            
            graphics.clear();
            graphics.drawGraphicsData(graphicsData);
            
            var vector:Vector.<Point> = model.touchPoints;
            var n:uint = vector.length;
            for (var i:int = 0; i < n; i++) {
                var p:Point = vector[i];
                drawTouchPoint(p.x, p.y);
            }
        }

        private function drawTouchPoint(x:Number, y:Number):void{
            graphics.beginFill(0xCC0033, 0.25);
            graphics.drawCircle(x, y, 20);
            graphics.endFill();
        }
    }


    import flash.geom.Point;
    
    class Coordinate {
        // 外部から入力するデータ
        // 静的変数
        // バネ係数
        static public function set spring(value:Number):void { _spring = value; }
        static private var _spring:Number = 0.02;
        // 抵抗
        static public function set friction(value:Number):void { _friction = value; }
        static private var _friction:Number = 0.92;
        // 反応距離
        static public function set distanceOfReaction(value:Number):void { _distanceOfReaction = value; }
        static private var _distanceOfReaction:Number = 100;

        // 外部へ出力するデータ
        // 現在座標
        public function get x():Number { return _x; }
        private var _x:Number;
        public function get y():Number { return _y; }
        private var _y:Number;

        
        // 内部だけで使用するデータ
        // 既定座標
        private var localX:Number;
        private var localY:Number;
        // 速度
        private var vx:Number = 0.0;
        private var vy:Number = 0.0;
    

        public function Coordinate(valueX:Number, valueY:Number) {
            _x = localX = valueX;
            _y = localY = valueY;
        }
    
        public function update(mousePoint:Point):void {
            // マウスの位置と自分との距離を求める
            var distance:Number = Point.distance(mousePoint, new Point(localX, localY));
        
            // 到達値
            var dx:Number;
            var dy:Number;
            // 到達値の計算
            if (distance < _distanceOfReaction) {
                var diff:Number     = -distance * (_distanceOfReaction - distance) / _distanceOfReaction;
                var radian:Number   = Math.atan2(mousePoint.y - localY, mousePoint.x - localX);
                var diffPoint:Point = Point.polar(diff * 2.5, radian);
                dx = localX + diffPoint.x;
                dy = localY + diffPoint.y;
            } else{    // 位置を元に戻す
                dx = localX;
                dy = localY;
            }
        
            vx += (dx - _x) * _spring;
            vy += (dy - _y) * _spring;
            vx *= _friction;
            vy *= _friction;
            _x += vx;
            _y += vy;
        }
    }


    class Vertex2D {
        // X座標
        public function get x():Number { return _x; }
        public function set x(value:Number):void {
            _x = value;
        }
        private var _x:Number;
        
        // Y座標
        public function get y():Number { return _y; }
        public function set y(value:Number):void {
            _y = value;
        }
        private var _y:Number;
        
        
        public function Vertex2D(x:Number = 0.0, y:Number = 0.0) {
            _x = x;
            _y = y;
        }
    }