notice: Flash editor updated! Join the development! Thanks to MiniBuilder


forked from : miniapp's [diff(106)]

embed

FORKED
  1. // forked from miniapp's 布 :改善2
  2. /**
  3.  * 2次元だけど、出来たかな?
  4.  *
  5.  * やっぱり右によっている。
  6.  * 
  7.  * ドラッグでマウスに一番近いポイントを移動させる。
  8.  * ctrlキー押しながらドラッグで固定。
  9.  * ダブルクリックで固定を解除。
  10.  */
  11. package {
  12.     import flash.display.Sprite;
  13.     import flash.display.StageQuality;
  14.     import flash.display.StageScaleMode;
  15.     import flash.events.Event;
  16.     import flash.events.KeyboardEvent;
  17.     import flash.events.MouseEvent;
  18.     [SWF(backgroundColor="0xFFFFFF", width="465", height="465", frameRate="60")]
  19.     public class Cloth extends Sprite {
  20.         
  21.         public static const STAGE_WIDTH:uint = 465;
  22.         public static const STAGE_HEIGHT:uint = 465;
  23.         
  24.         public function Cloth() {
  25.             if (stage) init();
  26.             else addEventListener(Event.ADDED_TO_STAGE, init);
  27.         }
  28.         
  29.         private var _lineColor:uint = 0x000000;
  30.         private var _cols:uint = 16;//横の数
  31.         private var _rows:uint = 16;//縦の数
  32.         private var _diffX:uint = 10;
  33.         private var _diffY:uint = 10;
  34.         private var _isCtrlPress:Boolean = false;
  35.         private var _isMouseDown:Boolean = false;
  36.         private var _draggedPoint:Point;
  37.         private var _isFirst:Boolean = false;
  38.         private var _numJoints:uint;
  39.         private var _joints:Vector.<Joint> = new Vector.<Joint>();
  40.         private var _points:Vector.<Point> = new Vector.<Point>();
  41.         private var _pointsXs:Vector.<Vector.<Point>> = new Vector.<Vector.<Point>>(_rows, true);
  42.         private var _pointsYs:Vector.<Vector.<Point>> = new Vector.<Vector.<Point>>(_cols, true);
  43.         
  44.         private function init(e:Event = null):void {
  45.             removeEventListener(Event.ADDED_TO_STAGE, init);
  46.             stage.scaleMode = StageScaleMode.NO_SCALE;
  47.             //stage.quality = StageQuality.MEDIUM;
  48.             
  49.             stage.doubleClickEnabled = true;
  50.             stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
  51.             stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDwonHandler);
  52.             stage.addEventListener(MouseEvent.DOUBLE_CLICK, doubleClickHandler);
  53.             stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDonwHandler);
  54.             stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
  55.             
  56.             putPoint();
  57.             joint();
  58.             
  59.             //上端2つを固定します。
  60.             //左端
  61.             var point1:Point = _pointsXs[0][0];
  62.             point1.x = 200;
  63.             point1.y = 130;
  64.             point1.isPinned = true;
  65.             
  66.             //右端
  67.             var point2:Point = _pointsXs[0][_rows - 1];
  68.             point2.x = STAGE_WIDTH - 100;
  69.             point2.y = 10;
  70.             point2.isPinned = true;
  71.             
  72.             addEventListener(Event.ENTER_FRAME, enterFrameHandler);
  73.         }
  74.         
  75.         /**
  76.          * ポイントを配置します。
  77.          */
  78.         private function putPoint():void {
  79.             //縦方向に並べたポイントを入れる配列を先に用意する
  80.             for (var i:uint = 0; i < _cols; i++) { 
  81.                 var pointsY:Vector.<Point> = new Vector.<Point>(_rows, true);
  82.                 _pointsYs[i] = pointsY;
  83.             }
  84.             
  85.             var clothWidth:Number = (_cols - 1) * _diffX;
  86.             var clothHeight:Number = (_rows - 1) * _diffY;
  87.             var startX:Number = (STAGE_WIDTH - clothWidth) / 2;
  88.             var startY:Number = (STAGE_HEIGHT - clothHeight) / 2;
  89.             
  90.             //ポイントを格子状に配置
  91.             for (i = 0; i < _rows; i++) {
  92.                 var pointsX:Vector.<Point> = new Vector.<Point>(_cols, true);
  93.                 _pointsXs[i] = pointsX;
  94.                 for (var j:uint = 0; j < _cols; j++) {
  95.                     var point:Point = new Point();
  96.                     _points.push(point);
  97.                     point.name = String(i) + "-" + String(j);//デバッグ用
  98.                     point.x = startX + _diffX * j;
  99.                     point.y = startY + _diffY * i;
  100.                     
  101.                     //横に並ぶポイントを入れる
  102.                     pointsX[j] = point;
  103.                     
  104.                     //縦方向に並ぶポイントを入れる
  105.                     pointsY = _pointsYs[j];
  106.                     pointsY[i] = point;
  107.                 }
  108.             }
  109.             _points.fixed = true;
  110.         }
  111.         
  112.         private function joint():void {
  113.             for (var i:uint; i < _rows; i++) {
  114.                 for (var j:uint = 0; j < _cols; j++) {
  115.                     var point:Point = _pointsXs[i][j];
  116.                     if (j > 0) {
  117.                         var leftPoint:Point = _pointsXs[i][j - 1 ];
  118.                         _joints.push(new Joint(leftPoint, point));
  119.                         _joints.push(new Joint(point, leftPoint));
  120.                     }
  121.                     
  122.                     if (i > 0) {
  123.                         var upPoint:Point = _pointsXs[i - 1][j];
  124.                         _joints.push(new Joint(upPoint, point));
  125.                         _joints.push(new Joint(point, upPoint));
  126.                     }
  127.                 }
  128.             }
  129.             
  130.             _numJoints = _joints.length;
  131.             _joints.fixed = true;
  132.         }
  133.         
  134.         /**
  135.          * 一番カーソルに近いポイントを捜す。
  136.          */
  137.         private function searchPoint():Point {
  138.             var lastMinDist:Number = Infinity;
  139.             var target:Point;
  140.             for each(var point:Point in _points) {
  141.                 var dx:Number = point.x - mouseX;
  142.                 var dy:Number = point.y - mouseY;
  143.                 var dist:Number = Math.sqrt(dx * dx + dy * dy);
  144.                 if (dist < lastMinDist) {
  145.                     lastMinDist = dist;
  146.                     target = point;
  147.                 }
  148.             }
  149.             return target;
  150.         }
  151.         
  152.         /**
  153.          * ポイント同士を繋ぐ線を書く
  154.          */
  155.         private function drawLine():void {
  156.             graphics.clear();
  157.             graphics.lineStyle(1, _lineColor);
  158.             //横のラインを引く
  159.             for each(var pointsX:Vector.<Point> in _pointsXs){
  160.                 //横列のポイントが入った配列にアクセス。
  161.                 var firstPoint:Point = pointsX[0];
  162.                 graphics.moveTo(firstPoint.x, firstPoint.y);
  163.                 for (var i:uint = 1; i < _cols; i++) {
  164.                     var point:Point = pointsX[i];
  165.                     graphics.lineTo(point.x, point.y);
  166.                 }
  167.             }
  168.             
  169.             for each(var pointsY:Vector.<Point> in _pointsYs) {
  170.                 firstPoint = pointsY[0];
  171.                 graphics.moveTo(firstPoint.x, firstPoint.y);
  172.                 for (i = 1; i < _rows; i++) {
  173.                     point = pointsY[i];
  174.                     graphics.lineTo(point.x, point.y);
  175.                 }
  176.             }
  177.         }
  178.         
  179.         private function enterFrameHandler(e:Event):void {
  180.             if (_isMouseDown) {
  181.                 _draggedPoint.x = mouseX;
  182.                 _draggedPoint.y = mouseY;
  183.             }
  184.             
  185.             for each(var joint:Joint in _joints) {
  186.                 joint.update();
  187.             }
  188.             
  189.             drawLine();
  190.         }
  191.         
  192.         private function keyDonwHandler(e:KeyboardEvent = null):void{
  193.             if(e.ctrlKey) _isCtrlPress = true;
  194.         }
  195.         
  196.         private function keyUpHandler(e:KeyboardEvent = null):void{
  197.             _isCtrlPress = false;
  198.         }
  199.         
  200.         private function doubleClickHandler(e:MouseEvent = null):void{
  201.             searchPoint().isPinned = false;
  202.         }
  203.         
  204.         private function mouseDwonHandler(e:MouseEvent):void {
  205.             _isMouseDown = true;
  206.             _draggedPoint = searchPoint();
  207.             _draggedPoint.isDragging = true;
  208.         }
  209.         
  210.         private function mouseUpHandler(e:MouseEvent):void    {
  211.             _isMouseDown = false;
  212.             if (_isCtrlPress)
  213.                 _draggedPoint.isPinned = true;
  214.             _draggedPoint.isDragging = false;
  215.             _draggedPoint = undefined;
  216.         }
  217.     }
  218. }
  219. class Joint {
  220.     
  221.     public static var SPRING:Number = 0.08;
  222.     public static var FRICTION:Number = 0.96;
  223.     public static var GRAVITY:Number = 0.45;
  224.     
  225.     public function Joint(point:Point, target:Point) { 
  226.         var initDx:Number = target.x - point.x;
  227.         var initDy:Number = target.y - point.y;
  228.         var length:Number = Math.sqrt(initDx * initDx + initDy * initDy);
  229.         
  230.         //バネ運動させる関数
  231.         update = function():void {
  232.             if (point.isDragging || point.isPinned)
  233.                 return;
  234.             
  235.             var dx:Number = target.x - point.x;
  236.             var dy:Number = target.y - point.y;
  237.             var angle:Number = Math.atan2(dy, dx);
  238.             
  239.             var targetX:Number = target.x - length * Math.cos(angle);
  240.             var targetY:Number = target.y - length * Math.sin(angle);
  241.             
  242.             point.vx += (targetX - point.x) * Joint.SPRING;
  243.             point.vy += (targetY - point.y) * Joint.SPRING;
  244.             point.x += (point.vx *= FRICTION);
  245.             point.y += (point.vy *= FRICTION);
  246.             point.y += GRAVITY;
  247.         }
  248.     }
  249.     
  250.     public var update:Function;
  251. }
  252. class Point {
  253.     public var name:String;
  254.     public var x:Number;
  255.     public var y:Number;
  256.     public var vx:Number = 0;
  257.     public var vy:Number = 0;
  258.     public var isPinned:Boolean = false;
  259.     public var isDragging:Boolean = false;
  260. }
noswf
Get Adobe Flash Player