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;
}
}