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

flash on 2011-6-7

Get Adobe Flash player
by bashi 07 Jun 2011
    Embed
/**
 * Copyright bashi ( http://wonderfl.net/user/bashi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/v4js
 */

package {
    import flash.text.TextField;
    import flash.events.MouseEvent;
    import flash.events.Event;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    public class FlashTest extends Sprite {
        /** 固定するx座標。 */
        private var _fixedX:Number;
        /** 節間の距離。 */
        private var _dist:Number = 20;
        /** 節の数。 */
        private var _pointCnt:int = 10;
        /** 重力加速度。 */
        private var _gravity:Number = .8;
        /** 硬さ。 */
        private var _hardness:int = 3;
        /** 重り。 */
        private var _sinker:Object;
        /** 節の配列。 */
        private var _pointArray:Array;
        /** 掴んでいる節。 */
        private var _graspTarget:Object = null;
        /**
         * コンストラクタ。
         */
        public function FlashTest() {
            // ステージの設定をする
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT
            // パラメータの初期化をする
            _fixedX = stage.stageWidth / 2;
            // 節を準備する
            _pointArray = [];
            for (var i:int = 0; i < _pointCnt; i++) {
                var point:Object = createPoint(i);
                _pointArray.push(point);
            }
            // 重りを生成する
            _sinker = createSinker();
            _pointArray.push(_sinker);
            // フレームイベントリスナを登録する
            addEventListener(Event.ENTER_FRAME, doEnterFrame);
            // マウスアップでつかんでいるものを離す
            stage.addEventListener(MouseEvent.MOUSE_UP,
                function (e:MouseEvent):void {
                    _graspTarget = null;
                });
        }
        /**
         * フレームイベントハンドラです。
         * @param e イベントオブジェクト
         */
        protected function doEnterFrame(e:Event):void {
            // 節の位置を更新する
            for each (var point:Object in _pointArray) {
                // 重力加速度により位置を移動する
                point.y += _gravity;
                // 位置を一旦保存する
                var orgX:Number = point.x;
                var orgY:Number = point.y;
                // 前回位置からの移動量により位置を更新する
                point.x += point.x - point.prevX;
                point.y += point.y - point.prevY;
                // 前回位置を更新する
                point.prevX = orgX;
                point.prevY = orgY;
            }
            // 節間の距離を調整する
            for (var j:int = 0; j < _hardness; j++) {
                for (var i:int = 0, iEnd:int = _pointArray.length - 1; i < iEnd; i++) {
                    var point1:Object = _pointArray[i];
                    var point2:Object = _pointArray[i + 1];
                    // 節間の距離を算出する
                    var dx:Number = point2.x - point1.x;
                    var dy:Number = point2.y - point1.y;
                    var d:Number = Math.sqrt(dx * dx + dy * dy);
                    // 指定された間隔と現在の距離との差 / 2を各点の移動量とする
                    dx = (_dist - d) / 2 * dx / d;
                    dy = (_dist - d) / 2 * dy / d;
                    // 節を移動する
                    point1.x -= dx;
                    point1.y -= dy;
                    point2.x += dx;
                    point2.y += dy;
                }
                // 最初の節は天井に固定する
                _pointArray[0].x = _pointArray[0].prevX = _fixedX;
                _pointArray[0].y = _pointArray[0].prevY = 0;
                // つかんでいる節はマウスカーソルの位置にする
                if (_graspTarget) {
                    _graspTarget.x = _graspTarget.prevX = mouseX;
                    _graspTarget.y = _graspTarget.prevY = mouseY;
                }
            }
            // 表示オブジェクトの位置を更新する
            for (i = 0, iEnd = _pointArray.length; i < iEnd; i++) {
                point = _pointArray[i];
                point.sprite.x = point.x;
                point.sprite.y = point.y;
            }
            // 重りの向きを調整する
            var lastPointSprite:Sprite = _pointArray[_pointArray.length - 2].sprite;
            var angle:Number = Math.atan2(
                lastPointSprite.y - _sinker.sprite.y,
                lastPointSprite.x - _sinker.sprite.x);
            _sinker.sprite.rotation = angle * 180 / Math.PI;
        }

        /**
         * 節を生成し、戻します。
         * @param idx インデックス
         * @return 節をあらわすオブジェクト
         */
        protected function createPoint(idx:int):Object {
            // 表示オブジェクトを生成する
            var sprite:Sprite = new Sprite();
            sprite.graphics.lineStyle(1, 0x0000FF);
            sprite.graphics.beginFill(0xFFFFFF);
            sprite.graphics.drawCircle(0, 0, 10);
            sprite.graphics.endFill();
            sprite.x = _fixedX + _dist * idx;
            sprite.y = 0;
            addChild(sprite);
            // オブジェクトを生成する
            var obj:Object = {sprite:sprite, x:sprite.x, y:sprite.y, prevX:sprite.x, prevY:sprite.y};
            // マウスダウンで掴む
            sprite.addEventListener(MouseEvent.MOUSE_DOWN, createMouseDownHandler(obj));
            return obj;
        }

        /**
         * 重りを生成し、戻します。
         * @return 重りをあらわすオブジェクト
         */
        protected function createSinker():Object {
            // 表示オブジェクトを生成する
            var sprite:Sprite = new Sprite();
            sprite.graphics.beginFill(0x9999FF);
            sprite.graphics.drawCircle(0, 0, 20);
            sprite.graphics.endFill();
            sprite.graphics.beginFill(0x0000FF);
            sprite.graphics.drawCircle(10, 0, 10);
            sprite.graphics.endFill();
            sprite.x = _fixedX + _dist * _pointCnt;
            sprite.y = 0;
            addChild(sprite);
            // オブジェクトを生成する
            var obj:Object = {sprite:sprite, x:sprite.x, y:sprite.y, prevX:sprite.x, prevY:sprite.y};
            // マウスダウンで掴む
            sprite.addEventListener(MouseEvent.MOUSE_DOWN, createMouseDownHandler(obj));
            return obj;
        }
        /**
         * マウスダウンイベントハンドラを生成し、戻します。
         * @param point 対象となる節
         * @return ハンドラ
         */
        private function createMouseDownHandler(point:Object):Function {
            return function (e:MouseEvent):void {
                // 対象を保持する
                _graspTarget = point;
            };
        }
    }
}