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


embed

FAVORITE BY
:
graphics布がゆれる
:
clothphysicsspringtextile effect
:
:
Oeject
:
:
:
:
effectphysicsCloth Simulation
:
:
:
ゴム紐を左右に伸ばすと、左右対称に引っ張り合うけど、先に左手を離したら右に飛んでくから?
:
nice work!
:
私もこういうスクリプトをかけるようになりたい
:
こういうスクリプトをかけるようになりたい
FORKED
  1. /**
  2.  * 2次元だけど、出来たかな?
  3.  * 
  4.  * あいかわらず右によってる。
  5.  *
  6.  * ドラッグでマウスに一番近いポイントを移動させる。
  7.  * ctrlキー押しながらドラッグで固定。
  8.  * ダブルクリックで固定を解除。
  9.  */
  10. package {
  11.     import flash.display.Sprite;
  12.     import flash.display.StageQuality;
  13.     import flash.display.StageScaleMode;
  14.     import flash.events.Event;
  15.     import flash.events.KeyboardEvent;
  16.     import flash.events.MouseEvent;
  17.     [SWF(backgroundColor="0xFFFFFF", width="465", height="465", frameRate="60")]
  18.     public class Cloth extends Sprite {
  19.         
  20.         public static const STAGE_WIDTH:uint = 465;
  21.         public static const STAGE_HEIGHT:uint = 465;
  22.         
  23.         public function Cloth() {
  24.             if (stage) init();
  25.             else addEventListener(Event.ADDED_TO_STAGE, init);
  26.         }
  27.         
  28.         private var _lineColor:uint = 0x000000;
  29.         private var _cols:uint = 16;//横の数
  30.         private var _rows:uint = 16;//縦の数
  31.         private var _diffX:uint = 10;
  32.         private var _diffY:uint = 10;
  33.         private var _isCtrlPress:Boolean = false;
  34.         private var _isMouseDown:Boolean = false;
  35.         private var _draggedPoint:Point;
  36.         private var _isFirst:Boolean = false;
  37.         private var _numJoints:uint;
  38.         private var _joints:Vector.<Joint> = new Vector.<Joint>();
  39.         private var _points:Vector.<Point> = new Vector.<Point>();
  40.         private var _pointsXs:Vector.<Vector.<Point>> = new Vector.<Vector.<Point>>(_rows, true);
  41.         private var _pointsYs:Vector.<Vector.<Point>> = new Vector.<Vector.<Point>>(_cols, true);
  42.         
  43.         private function init(e:Event = null):void {
  44.             removeEventListener(Event.ADDED_TO_STAGE, init);
  45.             stage.scaleMode = StageScaleMode.NO_SCALE;
  46.             //stage.quality = StageQuality.MEDIUM;
  47.             
  48.             stage.doubleClickEnabled = true;
  49.             stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
  50.             stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDwonHandler);
  51.             stage.addEventListener(MouseEvent.DOUBLE_CLICK, doubleClickHandler);
  52.             stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDonwHandler);
  53.             stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
  54.             
  55.             putPoint();
  56.             joint();
  57.             
  58.             //上端2つを固定します。
  59.             //左端
  60.             var point1:Point = _pointsXs[0][0];
  61.             point1.x = 100;
  62.             point1.y = 10;
  63.             point1.isPinned = true;
  64.             
  65.             //右端
  66.             var point2:Point = _pointsXs[0][_cols - 1];
  67.             point2.x = STAGE_WIDTH - 100;
  68.             point2.y = 10;
  69.             point2.isPinned = true;
  70.             
  71.             addEventListener(Event.ENTER_FRAME, enterFrameHandler);
  72.         }
  73.         
  74.         /**
  75.          * ポイントを配置します。
  76.          */
  77.         private function putPoint():void {
  78.             //縦方向に並べたポイントを入れる配列を先に用意する
  79.             for (var i:uint = 0; i < _cols; i++) { 
  80.                 var pointsY:Vector.<Point> = new Vector.<Point>(_rows, true);
  81.                 _pointsYs[i] = pointsY;
  82.             }
  83.             
  84.             var clothWidth:Number = (_cols - 1) * _diffX;
  85.             var clothHeight:Number = (_rows - 1) * _diffY;
  86.             var startX:Number = (STAGE_WIDTH - clothWidth) / 2;
  87.             var startY:Number = (STAGE_HEIGHT - clothHeight) / 2;
  88.             
  89.             //ポイントを格子状に配置
  90.             for (i = 0; i < _rows; i++) {
  91.                 var pointsX:Vector.<Point> = new Vector.<Point>(_cols, true);
  92.                 _pointsXs[i] = pointsX;
  93.                 for (var j:uint = 0; j < _cols; j++) {
  94.                     var point:Point = new Point();
  95.                     _points.push(point);
  96.                     point.name = String(i) + "-" + String(j);//デバッグ用
  97.                     point.x = startX + _diffX * j;
  98.                     point.y = startY + _diffY * i;
  99.                     
  100.                     //横に並ぶポイントを入れる
  101.                     pointsX[j] = point;
  102.                     
  103.                     //縦方向に並ぶポイントを入れる
  104.                     pointsY = _pointsYs[j];
  105.                     pointsY[i] = point;
  106.                 }
  107.             }
  108.             _points.fixed = true;
  109.         }
  110.         
  111.         private function joint():void {
  112.             for (var i:uint; i < _rows; i++) {
  113.                 for (var j:uint = 0; j < _cols; j++) {
  114.                     var point:Point = _pointsXs[i][j];
  115.                     if (j > 0) {
  116.                         var leftPoint:Point = _pointsXs[i][j - 1 ];
  117.                         _joints.push(new Joint(leftPoint, point));
  118.                         _joints.push(new Joint(point, leftPoint));
  119.                     }
  120.                     
  121.                     if (i > 0) {
  122.                         var upPoint:Point = _pointsXs[i - 1][j];
  123.                         _joints.push(new Joint(upPoint, point));
  124.                         _joints.push(new Joint(point, upPoint));
  125.                     }
  126.                 }
  127.             }
  128.             
  129.             _numJoints = _joints.length;
  130.             _joints.fixed = true;
  131.         }
  132.         
  133.         /**
  134.          * 一番カーソルに近いポイントを捜す。
  135.          */
  136.         private function searchPoint():Point {
  137.             var lastMinDist:Number = Infinity;
  138.             var target:Point;
  139.             for each(var point:Point in _points) {
  140.                 var dx:Number = point.x - mouseX;
  141.                 var dy:Number = point.y - mouseY;
  142.                 var dist:Number = Math.sqrt(dx * dx + dy * dy);
  143.                 if (dist < lastMinDist) {
  144.                     lastMinDist = dist;
  145.                     target = point;
  146.                 }
  147.             }
  148.             return target;
  149.         }
  150.         
  151.         /**
  152.          * ポイント同士を繋ぐ線を書く
  153.          */
  154.         private function drawLine():void {
  155.             graphics.clear();
  156.             graphics.lineStyle(1, _lineColor);
  157.             //横のラインを引く
  158.             for each(var pointsX:Vector.<Point> in _pointsXs){
  159.                 //横列のポイントが入った配列にアクセス。
  160.                 var firstPoint:Point = pointsX[0];
  161.                 graphics.moveTo(firstPoint.x, firstPoint.y);
  162.                 for (var i:uint = 1; i < _cols; i++) {
  163.                     var point:Point = pointsX[i];
  164.                     graphics.lineTo(point.x, point.y);
  165.                 }
  166.             }
  167.             
  168.             for each(var pointsY:Vector.<Point> in _pointsYs) {
  169.                 firstPoint = pointsY[0];
  170.                 graphics.moveTo(firstPoint.x, firstPoint.y);
  171.                 for (i = 1; i < _rows; i++) {
  172.                     point = pointsY[i];
  173.                     graphics.lineTo(point.x, point.y);
  174.                 }
  175.             }
  176.         }
  177.         
  178.         private function enterFrameHandler(e:Event):void {
  179.             if (_isMouseDown) {
  180.                 _draggedPoint.x = mouseX;
  181.                 _draggedPoint.y = mouseY;
  182.             }
  183.             
  184.             for each(var joint:Joint in _joints) {
  185.                 joint.update();
  186.             }
  187.             
  188.             drawLine();
  189.         }
  190.         
  191.         private function keyDonwHandler(e:KeyboardEvent = null):void{
  192.             if(e.ctrlKey) _isCtrlPress = true;
  193.         }
  194.         
  195.         private function keyUpHandler(e:KeyboardEvent = null):void{
  196.             _isCtrlPress = false;
  197.         }
  198.         
  199.         private function doubleClickHandler(e:MouseEvent = null):void{
  200.             searchPoint().isPinned = false;
  201.         }
  202.         
  203.         private function mouseDwonHandler(e:MouseEvent):void {
  204.             _isMouseDown = true;
  205.             _draggedPoint = searchPoint();
  206.             _draggedPoint.isDragging = true;
  207.         }
  208.         
  209.         private function mouseUpHandler(e:MouseEvent):void    {
  210.             _isMouseDown = false;
  211.             if (_isCtrlPress)
  212.                 _draggedPoint.isPinned = true;
  213.             _draggedPoint.isDragging = false;
  214.             _draggedPoint = undefined;
  215.         }
  216.     }
  217. }
  218. class Joint {
  219.     
  220.     public static var SPRING:Number = 0.08;
  221.     public static var FRICTION:Number = 0.96;
  222.     public static var GRAVITY:Number = 0.45;
  223.     
  224.     public function Joint(point:Point, target:Point) { 
  225.         var initDx:Number = target.x - point.x;
  226.         var initDy:Number = target.y - point.y;
  227.         var length:Number = Math.sqrt(initDx * initDx + initDy * initDy);
  228.         
  229.         //バネ運動させる関数
  230.         update = function():void {
  231.             if (point.isDragging || point.isPinned)
  232.                 return;
  233.             
  234.             var dx:Number = target.x - point.x;
  235.             var dy:Number = target.y - point.y;
  236.             /*
  237.             var angle:Number = Math.atan2(dy, dx);
  238.             var targetX:Number = target.x - length * Math.cos(angle);
  239.             var targetY:Number = target.y - length * Math.sin(angle);
  240.             /**/
  241.             //*
  242.             //Math.cos(angle) は dx / distanceと同じ
  243.             //Math.sin(angle) は dy / distanceと同じ
  244.             var distance:Number = Math.sqrt(dx * dx + dy * dy);
  245.             var targetX:Number = target.x - length * dx / distance;
  246.             var targetY:Number = target.y - length * dy / distance;
  247.             /**/
  248.             
  249.             point.vx += (targetX - point.x) * Joint.SPRING;
  250.             point.vy += (targetY - point.y) * Joint.SPRING;
  251.             point.x += (point.vx *= FRICTION);
  252.             point.y += (point.vy *= FRICTION);
  253.             point.y += GRAVITY;
  254.         }
  255.     }
  256.     
  257.     public var update:Function;
  258. }
  259. class Point {
  260.     public var name:String;
  261.     public var x:Number;
  262.     public var y:Number;
  263.     public var z:Number;
  264.     public var vx:Number = 0;
  265.     public var vy:Number = 0;
  266.     public var vz:Number = 0;
  267.     public var isPinned:Boolean = false;
  268.     public var isDragging:Boolean = false;
  269. }
noswf
  1. // forked from miniapp's 布
  2. /**
  3.  * 本格的な布のシミュレーションではありません。
  4.  *
  5.  * 以前のバージョンは8方向に対して繋げていたが、
  6.  * 上下左右の4方向で十分だった。
  7.  * joint関数は凄く簡単になった。
  8.  *
  9.  * ドラッグでマウスに一番近いポイントを移動させる。
  10.  * ctrlキー押しながらドラッグで固定。
  11.  * ダブルクリックで固定を解除。
  12.  *
  13.  */
  14. package {
  15.     import flash.display.Sprite;
  16.     import flash.display.StageQuality;
  17.     import flash.display.StageScaleMode;
  18.     import flash.events.Event;
  19.     import flash.events.KeyboardEvent;
  20.     import flash.events.MouseEvent;
  21.     [SWF(backgroundColor="0xFFFFFF", width="465", height="465", frameRate="60")]
  22.     public class Cloth extends Sprite {
  23.         
  24.         public static const STAGE_WIDTH:uint = 465;
  25.         public static const STAGE_HEIGHT:uint = 465;
  26.         
  27.         public function Cloth() {
  28.             if (stage) init();
  29.             else addEventListener(Event.ADDED_TO_STAGE, init);
  30.         }
  31.         
  32.         private var _lineColor:uint = 0x000000;
  33.         private var _cols:uint = 16;//横の数
  34.         private var _rows:uint = 16;//縦の数
  35.         private var _diffX:uint = 10;
  36.         private var _diffY:uint = 10;
  37.         private var _isCtrlPress:Boolean = false;
  38.         private var _isMouseDown:Boolean = false;
  39.         private var _draggedPoint:Point;
  40.         private var _isFirst:Boolean = false;
  41.         private var _numJoints:uint;
  42.         private var _joints:Vector.<Joint> = new Vector.<Joint>();
  43.         private var _points:Vector.<Point> = new Vector.<Point>();
  44.         private var _pointsXs:Vector.<Vector.<Point>> = new Vector.<Vector.<Point>>(_rows, true);
  45.         private var _pointsYs:Vector.<Vector.<Point>> = new Vector.<Vector.<Point>>(_cols, true);
  46.         
  47.         private function init(e:Event = null):void {
  48.             removeEventListener(Event.ADDED_TO_STAGE, init);
  49.             stage.scaleMode = StageScaleMode.NO_SCALE;
  50.             //stage.quality = StageQuality.MEDIUM;
  51.             
  52.             stage.doubleClickEnabled = true;
  53.             stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
  54.             stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDwonHandler);
  55.             stage.addEventListener(MouseEvent.DOUBLE_CLICK, doubleClickHandler);
  56.             stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDonwHandler);
  57.             stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
  58.             
  59.             putPoint();
  60.             joint();
  61.             
  62.             //上端2つを固定します。
  63.             //左端
  64.             var point1:Point = _pointsXs[0][0];
  65.             point1.x = 100;
  66.             point1.y = 10;
  67.             point1.isPinned = true;
  68.             
  69.             //右端
  70.             var point2:Point = _pointsXs[0][_rows - 1];
  71.             point2.x = STAGE_WIDTH - 100;
  72.             point2.y = 10;
  73.             point2.isPinned = true;
  74.             
  75.             addEventListener(Event.ENTER_FRAME, enterFrameHandler);
  76.         }
  77.         
  78.         /**
  79.          * ポイントを配置します。
  80.          */
  81.         private function putPoint():void {
  82.             //縦方向に並べたポイントを入れる配列を先に用意する
  83.             for (var i:uint = 0; i < _cols; i++) { 
  84.                 var pointsY:Vector.<Point> = new Vector.<Point>(_rows, true);
  85.                 _pointsYs[i] = pointsY;
  86.             }
  87.             
  88.             var clothWidth:Number = (_cols - 1) * _diffX;
  89.             var clothHeight:Number = (_rows - 1) * _diffY;
  90.             var startX:Number = (STAGE_WIDTH - clothWidth) / 2;
  91.             var startY:Number = (STAGE_HEIGHT - clothHeight) / 2;
  92.             
  93.             //ポイントを格子状に配置
  94.             for (i = 0; i < _rows; i++) {
  95.                 var pointsX:Vector.<Point> = new Vector.<Point>(_cols, true);
  96.                 _pointsXs[i] = pointsX;
  97.                 for (var j:uint = 0; j < _cols; j++) {
  98.                     var point:Point = new Point();
  99.                     _points.push(point);
  100.                     point.name = String(i) + "-" + String(j);//デバッグ用
  101.                     point.x = startX + _diffX * j;
  102.                     point.y = startY + _diffY * i;
  103.                     
  104.                     //横に並ぶポイントを入れる
  105.                     pointsX[j] = point;
  106.                     
  107.                     //縦方向に並ぶポイントを入れる
  108.                     pointsY = _pointsYs[j];
  109.                     pointsY[i] = point;
  110.                 }
  111.             }
  112.             _points.fixed = true;
  113.         }
  114.         
  115.         private function joint():void {
  116.             for (var i:uint; i < _rows; i++) {
  117.                 for (var j:uint = 0; j < _cols; j++) {
  118.                     var point:Point = _pointsXs[i][j];
  119.                     if (j > 0) {
  120.                         var leftPoint:Point = _pointsXs[i][j - 1 ];
  121.                         _joints.push(new Joint(leftPoint, point));
  122.                         _joints.push(new Joint(point, leftPoint));
  123.                     }
  124.                     
  125.                     if (i > 0) {
  126.                         var upPoint:Point = _pointsXs[i - 1][j];
  127.                         _joints.push(new Joint(upPoint, point));
  128.                         _joints.push(new Joint(point, upPoint));
  129.                     }
  130.                 }
  131.             }
  132.             
  133.             _numJoints = _joints.length;
  134.             _joints.fixed = true;
  135.         }
  136.         
  137.         /**
  138.          * 一番カーソルに近いポイントを捜す。
  139.          */
  140.         private function searchPoint():Point {
  141.             var lastMinDist:Number = Infinity;
  142.             var target:Point;
  143.             for each(var point:Point in _points) {
  144.                 var dx:Number = point.x - mouseX;
  145.                 var dy:Number = point.y - mouseY;
  146.                 var dist:Number = Math.sqrt(dx * dx + dy * dy);
  147.                 if (dist < lastMinDist) {
  148.                     lastMinDist = dist;
  149.                     target = point;
  150.                 }
  151.             }
  152.             return target;
  153.         }
  154.         
  155.         /**
  156.          * ポイント同士を繋ぐ線を書く
  157.          */
  158.         private function drawLine():void {
  159.             graphics.clear();
  160.             graphics.lineStyle(1, _lineColor);
  161.             //横のラインを引く
  162.             for each(var pointsX:Vector.<Point> in _pointsXs){
  163.                 //横列のポイントが入った配列にアクセス。
  164.                 var firstPoint:Point = pointsX[0];
  165.                 graphics.moveTo(firstPoint.x, firstPoint.y);
  166.                 for (var i:uint = 1; i < _cols; i++) {
  167.                     var point:Point = pointsX[i];
  168.                     graphics.lineTo(point.x, point.y);
  169.                 }
  170.             }
  171.             
  172.             for each(var pointsY:Vector.<Point> in _pointsYs) {
  173.                 firstPoint = pointsY[0];
  174.                 graphics.moveTo(firstPoint.x, firstPoint.y);
  175.                 for (i = 1; i < _rows; i++) {
  176.                     point = pointsY[i];
  177.                     graphics.lineTo(point.x, point.y);
  178.                 }
  179.             }
  180.         }
  181.         
  182.         private function enterFrameHandler(e:Event):void {
  183.             if (_isMouseDown) {
  184.                 _draggedPoint.x = mouseX;
  185.                 _draggedPoint.y = mouseY;
  186.             }
  187.             
  188.             for each(var joint:Joint in _joints) {
  189.                 joint.update();
  190.             }
  191.             
  192.             drawLine();
  193.         }
  194.         
  195.         private function keyDonwHandler(e:KeyboardEvent = null):void{
  196.             if(e.ctrlKey) _isCtrlPress = true;
  197.         }
  198.         
  199.         private function keyUpHandler(e:KeyboardEvent = null):void{
  200.             _isCtrlPress = false;
  201.         }
  202.         
  203.         private function doubleClickHandler(e:MouseEvent = null):void{
  204.             searchPoint().isPinned = false;
  205.         }
  206.         
  207.         private function mouseDwonHandler(e:MouseEvent):void {
  208.             _isMouseDown = true;
  209.             _draggedPoint = searchPoint();
  210.             _draggedPoint.isDragging = true;
  211.         }
  212.         
  213.         private function mouseUpHandler(e:MouseEvent):void    {
  214.             _isMouseDown = false;
  215.             if (_isCtrlPress)
  216.                 _draggedPoint.isPinned = true;
  217.             _draggedPoint.isDragging = false;
  218.             _draggedPoint = undefined;
  219.         }
  220.     }
  221. }
  222. class Joint {
  223.     
  224.     public static var SPRING:Number = 0.06;
  225.     public static var FRICTION:Number = 0.96;
  226.     public static var GRAVITY:Number = 0.008;
  227.     
  228.     public function Joint(point:Point, target:Point) { 
  229.         var initDx:Number = target.x - point.x;
  230.         var initDy:Number = target.y - point.y;
  231.         var length:Number = Math.sqrt(initDx * initDx + initDy * initDy);
  232.         var angle:Number = Math.atan2(initDy, initDx);
  233.         
  234.         var tx:Number = length * Math.cos(angle);
  235.         var ty:Number = length * Math.sin(angle);
  236.         
  237.         //バネ運動させる関数
  238.         update = function():void {
  239.             if (point.isDragging || point.isPinned)
  240.                 return;
  241.             
  242.             var dx:Number = target.x - tx - point.x;
  243.             var dy:Number = target.y - ty - point.y;
  244.             point.vx += dx * Joint.SPRING;
  245.             point.vy += dy * Joint.SPRING;
  246.             point.vy += GRAVITY;
  247.             point.x += (point.vx *= FRICTION);
  248.             point.y += (point.vy *= FRICTION);
  249.         }
  250.     }
  251.     
  252.     public var update:Function;
  253. }
  254. class Point {
  255.     public var name:String;
  256.     public var x:Number;
  257.     public var y:Number;
  258.     public var vx:Number = 0;
  259.     public var vy:Number = 0;
  260.     public var isPinned:Boolean = false;
  261.     public var isDragging:Boolean = false;
  262. }
noswf
  1. /**
  2.  * GraphicsPathCommandでラインを描画するバージョン。
  3.  * drawLine関数の中が違います。
  4.  *
  5.  * 本格的な布のシミュレーションではありません。
  6.  * 
  7.  * ドラッグでマウスに一番近いポイントを移動させる。
  8.  * ctrlキー押しながらドラッグで固定。
  9.  * ダブルクリックで固定を解除。
  10.  */
  11. package {
  12.     import flash.display.GraphicsPathCommand;
  13.     import flash.display.Sprite;
  14.     import flash.display.StageQuality;
  15.     import flash.display.StageScaleMode;
  16.     import flash.events.Event;
  17.     import flash.events.KeyboardEvent;
  18.     import flash.events.MouseEvent;
  19.     [SWF(backgroundColor="0xFFFFFF", width="465", height="465", frameRate="60")]
  20.     public class Cloth_DrawPath extends Sprite {
  21.         
  22.         public static const STAGE_WIDTH:uint = 465;
  23.         public static const STAGE_HEIGHT:uint = 465;
  24.         
  25.         public function Cloth_DrawPath() {
  26.             if (stage) init();
  27.             else addEventListener(Event.ADDED_TO_STAGE, init);
  28.         }
  29.         
  30.         private var _lineColor:uint = 0x000000;
  31.         private var _cols:uint = 16;//横の数
  32.         private var _rows:uint = 16;//縦の数
  33.         private var _diffX:uint = 10;
  34.         private var _diffY:uint = 10;
  35.         private var _isCtrlPress:Boolean = false;
  36.         private var _isMouseDown:Boolean = false;
  37.         private var _draggedPoint:Point;
  38.         private var _isFirst:Boolean = false;
  39.         private var _numJoints:uint;
  40.         private var _joints:Vector.<Joint> = new Vector.<Joint>();
  41.         private var _points:Vector.<Point> = new Vector.<Point>();
  42.         private var _pointsXs:Vector.<Vector.<Point>> = new Vector.<Vector.<Point>>(_rows, true);
  43.         private var _pointsYs:Vector.<Vector.<Point>> = new Vector.<Vector.<Point>>(_cols, true);
  44.         
  45.         private var _vertices:Vector.<Number> = new Vector.<Number>();
  46.         private var _commands:Vector.<int> = new Vector.<int>();
  47.         
  48.         private function init(e:Event = null):void {
  49.             removeEventListener(Event.ADDED_TO_STAGE, init);
  50.             stage.scaleMode = StageScaleMode.NO_SCALE;
  51.             //stage.quality = StageQuality.MEDIUM;
  52.             
  53.             stage.doubleClickEnabled = true;
  54.             stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
  55.             stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDwonHandler);
  56.             stage.addEventListener(MouseEvent.DOUBLE_CLICK, doubleClickHandler);
  57.             stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDonwHandler);
  58.             stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
  59.             
  60.             putPoint();
  61.             joint();
  62.             
  63.             //上端2つを固定します。
  64.             //左端
  65.             var point1:Point = _pointsXs[0][0];
  66.             point1.x = 100;
  67.             point1.y = 10;
  68.             point1.isPinned = true;
  69.             
  70.             //右端
  71.             var point2:Point = _pointsXs[0][_rows - 1];
  72.             point2.x = STAGE_WIDTH - 100;
  73.             point2.y = 10;
  74.             point2.isPinned = true;
  75.             
  76.             addEventListener(Event.ENTER_FRAME, enterFrameHandler);
  77.         }
  78.         
  79.         /**
  80.          * ポイントを配置します。
  81.          */
  82.         private function putPoint():void {
  83.             //縦方向に並べたポイントを入れる配列を先に用意する
  84.             for (var i:uint = 0; i < _cols; i++) { 
  85.                 var pointsY:Vector.<Point> = new Vector.<Point>(_rows, true);
  86.                 _pointsYs[i] = pointsY;
  87.             }
  88.             
  89.             var clothWidth:Number = (_cols - 1) * _diffX;
  90.             var clothHeight:Number = (_rows - 1) * _diffY;
  91.             var startX:Number = (STAGE_WIDTH - clothWidth) / 2;
  92.             var startY:Number = (STAGE_HEIGHT - clothHeight) / 2;
  93.             
  94.             //ポイントを格子状に配置
  95.             for (i = 0; i < _rows; i++) {
  96.                 var pointsX:Vector.<Point> = new Vector.<Point>(_cols, true);
  97.                 _pointsXs[i] = pointsX;
  98.                 for (var j:uint = 0; j < _cols; j++) {
  99.                     var point:Point = new Point();
  100.                     _points.push(point);
  101.                     point.name = String(i) + "-" + String(j);//デバッグ用
  102.                     point.x = startX + _diffX * j;
  103.                     point.y = startY + _diffY * i;
  104.                     
  105.                     //横に並ぶポイントを入れる
  106.                     pointsX[j] = point;
  107.                     
  108.                     //縦方向に並ぶポイントを入れる
  109.                     pointsY = _pointsYs[j];
  110.                     pointsY[i] = point;
  111.                 }
  112.             }
  113.             _points.fixed = true;
  114.         }
  115.         
  116.         private function joint():void {
  117.             
  118.             //00------01-------02
  119.             //|        |       |
  120.             //|        |       |
  121.             //|        |       |
  122.             //10------11-------12
  123.             //|        |       |
  124.             //|        |       |
  125.             //|        |       |
  126.             //20------21-------22
  127.             
  128.             for (var i:uint = 0; i < _rows; i++) {
  129.                 var up:Boolean = (i - 1) >= 0;//上の行があるか。
  130.                 var down:Boolean = (i + 1) < _rows;//下の行があるか。
  131.                 if (up)
  132.                     var pointsX0:Vector.<Point> = _pointsXs[i - 1];//一つ上の段
  133.                     
  134.                 var pointsX1:Vector.<Point> = _pointsXs[i];
  135.                 
  136.                 if (down)
  137.                     var pointsX2:Vector.<Point> = _pointsXs[i + 1];//一つ下の段
  138.                 
  139.                 for (var j:uint = 0; j < _cols; j++) {
  140.                     var left:Boolean = (j - 1) >= 0;//左の列があるか。
  141.                     var right:Boolean = (j + 1) < _cols;//右の列があるか。
  142.                     
  143.                     var point11:Point = pointsX1[j];//中央のポイント
  144.                     
  145.                     if (up) {
  146.                         var point01:Point = pointsX0[j];//上
  147.                         //trace(point01.name);
  148.                         _joints.push(new Joint(point11, point01));
  149.                     }
  150.                     
  151.                     if (left) { 
  152.                         var point10:Point = pointsX1[j -1];//左
  153.                         //trace(point10.name);
  154.                         _joints.push(new Joint(point11, point10));
  155.                         
  156.                         if (up) {
  157.                             var point00:Point = pointsX0[j - 1]; //左上
  158.                             //trace(point00.name);
  159.                             _joints.push(new Joint(point11, point00));
  160.                         }
  161.                         
  162.                         if (down) {
  163.                             var point20:Point = pointsX2[j -1];//左下
  164.                             //trace(point20.name);
  165.                             _joints.push(new Joint(point11, point20));
  166.                         }
  167.                     }
  168.                     
  169.                     if (right) { 
  170.                         var point12:Point = pointsX1[j + 1];//右
  171.                         //trace(point12.name);
  172.                         _joints.push(new Joint(point11, point12));
  173.                         
  174.                         if (up) {
  175.                             var point02:Point = pointsX0[j + 1];//右上
  176.                             //trace(point02.name);
  177.                             _joints.push(new Joint(point11, point02));
  178.                         }
  179.                         
  180.                         if (down) {
  181.                             var point22:Point = pointsX2[j + 1];//右下
  182.                             //trace(point22.name);
  183.                             _joints.push(new Joint(point11, point22));
  184.                         }
  185.                     }
  186.                     
  187.                     if (down) {
  188.                         var point21:Point = pointsX2[j];//下
  189.                         //trace(point21.name);
  190.                         _joints.push(new Joint(point11, point21));
  191.                     }
  192.                 }
  193.             }
  194.             _numJoints = _joints.length;
  195.             _joints.fixed = true;
  196.         }
  197.         
  198.         /**
  199.          * 一番カーソルに近いポイントを捜す。
  200.          */
  201.         private function searchPoint():Point {
  202.             var lastMinDist:Number = Infinity;
  203.             var target:Point;
  204.             for each(var point:Point in _points) {
  205.                 var dx:Number = point.x - mouseX;
  206.                 var dy:Number = point.y - mouseY;
  207.                 var dist:Number = Math.sqrt(dx * dx + dy * dy);
  208.                 if (dist < lastMinDist) {
  209.                     lastMinDist = dist;
  210.                     target = point;
  211.                 }
  212.             }
  213.             return target;
  214.         }
  215.         
  216.         /**
  217.          * ポイント同士を繋ぐ線を書く
  218.          */
  219.         private function drawLine():void {
  220.             graphics.clear();
  221.             graphics.lineStyle(1, _lineColor);
  222.             
  223.             var dataIndex:uint = 0;
  224.             var commandIndex:uint = 0;
  225.             for each(var pointsX:Vector.<Point> in _pointsXs){
  226.                 //横列のポイントが入った配列にアクセス。
  227.                 var firstBall:Point = pointsX[0];
  228.                 _vertices[dataIndex++] = firstBall.x;
  229.                 _vertices[dataIndex++] = firstBall.y;
  230.                 _commands[commandIndex++] = GraphicsPathCommand.MOVE_TO;
  231.                 
  232.                 for (var i:uint = 1; i < _cols; i++) {
  233.                     var ball:Point = pointsX[i];
  234.                     _vertices[dataIndex++] = ball.x;
  235.                     _vertices[dataIndex++] = ball.y;
  236.                     _commands[commandIndex++] = GraphicsPathCommand.LINE_TO;
  237.                 }
  238.             }
  239.             
  240.             for each(var ballsY:Vector.<Point> in _pointsYs) {
  241.                 firstBall = ballsY[0];
  242.                 _vertices[dataIndex++] = firstBall.x;
  243.                 _vertices[dataIndex++] = firstBall.y;
  244.                 _commands[commandIndex++] = GraphicsPathCommand.MOVE_TO;
  245.                 
  246.                 for (i = 1; i < _rows; i++) {
  247.                     ball = ballsY[i];
  248.                     _vertices[dataIndex++] = ball.x;
  249.                     _vertices[dataIndex++] = ball.y;
  250.                     _commands[commandIndex++] = GraphicsPathCommand.LINE_TO;
  251.                 }
  252.             }
  253.             if(_isFirst){
  254.                 _commands.fixed = _vertices.fixed = true;
  255.                 _isFirst = false;
  256.             }
  257.             graphics.drawPath(_commands, _vertices);
  258.         }
  259.         
  260.         private function enterFrameHandler(e:Event):void {
  261.             if (_isMouseDown) {
  262.                 _draggedPoint.x = mouseX;
  263.                 _draggedPoint.y = mouseY;
  264.             }
  265.             
  266.             for each(var joint:Joint in _joints) {
  267.                 joint.update();
  268.             }
  269.             
  270.             drawLine();
  271.         }
  272.         
  273.         private function keyDonwHandler(e:KeyboardEvent = null):void{
  274.             if(e.ctrlKey) _isCtrlPress = true;
  275.         }
  276.         
  277.         private function keyUpHandler(e:KeyboardEvent = null):void{
  278.             _isCtrlPress = false;
  279.         }
  280.         
  281.         private function doubleClickHandler(e:MouseEvent = null):void{
  282.             searchPoint().isPinned = false;
  283.         }
  284.         
  285.         private function mouseDwonHandler(e:MouseEvent):void {
  286.             _isMouseDown = true;
  287.             _draggedPoint = searchPoint();
  288.             _draggedPoint.isDragging = true;
  289.         }
  290.         
  291.         private function mouseUpHandler(e:MouseEvent):void    {
  292.             _isMouseDown = false;
  293.             if (_isCtrlPress)
  294.                 _draggedPoint.isPinned = true;
  295.             _draggedPoint.isDragging = false;
  296.             _draggedPoint = undefined;
  297.         }
  298.     }
  299. }
  300. class Joint {
  301.     
  302.     public static var SPRING:Number = 0.03;
  303.     public static var FRICTION:Number = 0.97;
  304.     public static var GRAVITY:Number = 0.005;
  305.     
  306.     public function Joint(point:Point, target:Point) { 
  307.         var initDx:Number = target.x - point.x;
  308.         var initDy:Number = target.y - point.y;
  309.         var length:Number = Math.sqrt(initDx * initDx + initDy * initDy);
  310.         var angle:Number = Math.atan2(initDy, initDx);
  311.         
  312.         var tx:Number = length * Math.cos(angle);
  313.         var ty:Number = length * Math.sin(angle);
  314.         
  315.         //バネ運動させる関数
  316.         update = function():void {
  317.             if (point.isDragging || point.isPinned)
  318.                 return;
  319.             
  320.             var dx:Number = target.x - tx - point.x;
  321.             var dy:Number = target.y - ty - point.y;
  322.             point.vx += dx * Joint.SPRING;
  323.             point.vy += dy * Joint.SPRING;
  324.             point.vy += GRAVITY;
  325.             point.x += (point.vx *= FRICTION);
  326.             point.y += (point.vy *= FRICTION);
  327.         }
  328.     }
  329.     
  330.     public var update:Function;
  331. }
  332. class Point {
  333.     public var name:String;
  334.     public var x:Number;
  335.     public var y:Number;
  336.     public var vx:Number = 0;
  337.     public var vy:Number = 0;
  338.     public var isPinned:Boolean = false;
  339.     public var isDragging:Boolean = false;
  340. }
noswf
Get Adobe Flash Player