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

[test]stagedrag

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

//
//    ステージをドラッグするとオブジェクトがそれに沿って動く処理のテスト
//    MOUSE_LEAVEはドラッグ中は送出されないので自前で座標計算を行って再現
//
package 
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.events.ContextMenuEvent;
    import flash.ui.ContextMenu;
    import flash.ui.ContextMenuItem;

    [SWF(width = "465", height = "465", frameRate = "60")]
    
    /**
     * ...
     * @author 
     */
    public class Main extends Sprite 
    {
        private var sp:Sprite;
        private var mouseInStage:Boolean = true;
        
        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            // entry point
            
            sp = new Sprite();
            sp.graphics.beginFill(0);
            sp.graphics.drawCircle(0, 0, 30);
            sp.graphics.endFill();
            sp.x = 465 / 2;
            sp.y = 465 / 2;
            
            addChild( sp );
            
            this.contextMenu = new ContextMenu();
            
            stage.addEventListener( MouseEvent.MOUSE_DOWN, MouseDownHandler );
            stage.addEventListener( MouseEvent.MOUSE_UP, MouseUpHandler );
            this.contextMenu.addEventListener( ContextMenuEvent.MENU_SELECT, OpenContextMenuHandler );
            addEventListener( Event.ENTER_FRAME, EnterFrameHandler );
                
        }
        
        /**
         * ステージ上でマウスが押された時に呼ばれる
         * @param    event
         */
        private function MouseDownHandler( event:MouseEvent ) : void
        {
            StageDragManager.getInstance().MouseDown( this.stage );
        }
        /**
         * ステージ上でマウスが離された時に呼ばれる
         * @param    event
         */
        private function MouseUpHandler( event:MouseEvent ) : void
        {
            StageDragManager.getInstance().MouseUp();
        }
        /**
         * コンテキストメニューが開かれた時に呼ばれる
         * @param    e
         */
        private function OpenContextMenuHandler( e:ContextMenuEvent ) : void
        {
            StageDragManager.getInstance().MouseUp();
        }
        
        private function EnterFrameHandler( e:Event ) : void
        {
            //    マウスが場外に出た判定(自前)
            //    場外に出た瞬間はMOUSE_UPと同じ状態にする
            if ( mouseInStage && (stage.mouseX < 0 || stage.mouseX >= stage.stageWidth || stage.mouseY < 0 || stage.mouseY >= stage.stageHeight) )
            {
                mouseInStage = false;
                MouseUpHandler( null );
            }else
            if ( stage.mouseX > 0 && stage.mouseX < stage.stageWidth && stage.mouseY > 0 && stage.mouseY < stage.stageHeight ) 
            {
                mouseInStage = true;
            }
            
            StageDragManager.getInstance().Update(this.stage);
            if ( StageDragManager.getInstance().dragflag )
            {
                sp.x += StageDragManager.getInstance().moveX;
                sp.y += StageDragManager.getInstance().moveY;
            }
        }
        
    }
    
}


    import flash.display.Stage;
    import flash.geom.Point;
    
    /**
     * ステージのドラッグ情報を管理するクラス(直接処理させるわけではない)
     * どっからでも参照したいのでシングルトンパターンで実装
     * @author 
     */
    class StageDragManager
    {
        private    static    var    instance:StageDragManager = null;
        private    static    var    callGetInstance:Boolean = false;    
                        
        public function StageDragManager() 
        {
            if ( callGetInstance ) {
                callGetInstance = false;    
            }else
            {
                throw new Error("コンストラクタの直接呼び出しは禁止");
            }
        }
        
        public static function getInstance() : StageDragManager
        {
            if ( StageDragManager.instance == null )
            {
                callGetInstance = true;
                StageDragManager.instance = new StageDragManager();
            }
            return    StageDragManager.instance;
        }        
    
        ///////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////
        private var mousedownFlag:Boolean = false;
        private var mousedownPoint:Point = new Point();
        private var dragFlag:Boolean = false;
        public function get dragflag():Boolean { return    dragFlag;    }
        private var prevMousePoint:Point = new Point();
        private var mouseMoveVector:Point = new Point();
        
        
        
        /**
         * ステージでマウスダウンが発生した時に呼び出すようにする
         * @param    stage
         */
        public function MouseDown(stage:Stage) : void
        {
            mousedownFlag = true;
            dragFlag = false;
            mousedownPoint.x = stage.mouseX;
            mousedownPoint.y = stage.mouseY;
        }
        
        /**
         * ステージでマウスアップが発生、もしくはそれに該当する処理が発生した時に呼び出すようにする
         */
        public function MouseUp() : void
        {
            mousedownFlag = false;
            dragFlag = false;
            mouseMoveVector.x = 0;
            mouseMoveVector.y = 0;
            
        }
        
        /**
         * 
         * @param    stage
         */
        public function Update(stage:Stage) : void
        {
            mouseMoveVector.x = 0;
            mouseMoveVector.y = 0;
            
            //    差分を見て、ある程度移動していたならドラッグ開始
            if ( !dragFlag && mousedownFlag )
            {
                var sx:Number = (stage.mouseX - mousedownPoint.x);
                var sy:Number = (stage.mouseY - mousedownPoint.y);
                if ( sx * sx + sy * sy > 5 * 5 )
                {
                    dragFlag = true;
                    prevMousePoint.x = stage.mouseX;
                    prevMousePoint.y = stage.mouseY;
                    mouseMoveVector.x = sx;
                    mouseMoveVector.y = sy;
                    trace("ドラッグ開始");
                }
            }else
            //    ドラッグ中は毎フレーム移動差分を取る
            if( dragFlag )
            {                                
                mouseMoveVector.x = stage.mouseX - prevMousePoint.x;
                mouseMoveVector.y = stage.mouseY - prevMousePoint.y;
                prevMousePoint.x = stage.mouseX;
                prevMousePoint.y = stage.mouseY;
            }
        }
        
        public function get moveX():Number { return    mouseMoveVector.x;    }
        public function get moveY():Number { return    mouseMoveVector.y;    }
        
    }