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

注意! タイトルは釣りです!!!!
言い訳(説明)は http://aquioux.blog48.fc2.com/blog-entry-651.html にて
@author YOSHIDA, Akio (Aquioux)
/**
 * Copyright fishKing ( http://wonderfl.net/user/fishKing )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/hEMe
 */

// 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);
			addChild(new Stats());
		}
	}
}


	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, i * intervalH + offsetY);
					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 * 4, 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;
		}
	}