AS3 DragManager ---- 自己写个拖动管理器

这个是自己为当前需求而写的一个拖动管理器;

比较轻量级,没有mx类库下的DragManager那么强大;


一般用于web game的各种拖动处理的话,够用了:


执行效果,如图:

AS3 DragManager ---- 自己写个拖动管理器_第1张图片


目前我们只能定义成,interface去扩展,因为纯as3的代码没有支持拖动的封装(除,Flex的mx.xxx.DragManager,这个是企业级的应用框架了)


被拖动接口的定义;

package view.common.interfaces
{
	import flash.display.DisplayObject;
	import flash.events.IEventDispatcher;

	/**
	 * 可拖动对象接口
	 * @author jave.lin
	 * @date 2013-6-9
	 */	
	public interface IDrag extends IEventDispatcher{
		/**获取绑定数据*/
		function getData():Object;
		/**设置绑定数据*/
		function setData(value:Object):void;
		/**拖动时的显示对象*/
		function getOnDragingDsp():DisplayObject;
		
		/**拖动开始后*/
		function onDragStartedHandler():void;
		/**拖动结束后*/
		function onDragEndedHandler():void;
		
		/**获取拖动容器对象*/
		function getContainer():IDragContainer;
		/**设置拖动容器对象*/
		function setContainer(value:IDragContainer):void;
		
		/**
		 * 当前能否拖动的标识
		 */		
		function get canDrag():Boolean;
	}
}


被拖动对象的容器接口;
package view.common.interfaces
{
	import flash.events.IEventDispatcher;

	/**
	 * 可拖动对象容器接口
	 * @author jave.lin
	 * @date 2013-6-9
	 */	
	public interface IDragContainer extends IEventDispatcher{
		/**在带有拖动物品时,移出该拖动容器时的处理*/
		function onDragOut(drager:IDrag):void;
		/**在带有拖动物品时,经过该拖动容器时的处理*/
		function onDragOver(drager:IDrag):void;
		/**在该拖动容器中松开鼠标*/
		function onDragDrop(drager:IDrag):void;
		/**获取当前容器的拖动对象*/
		function getDrager():IDrag;
		/**设置拖动对象*/
		function setDrager(value:IDrag):void;
	}
}

最后是我们的主角:DragDropManager类;

这里最要处理一些拖动的流程代码:

package view.common.drag
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.EventDispatcher;
	import flash.events.MouseEvent;
	
	import utils.DisplayUtil;
	
	import view.common.events.DragEvent;
	import view.common.interfaces.IDrag;
	import view.common.interfaces.IDragContainer;

	/**
	 * 拖放管理器
	 * @author jave.lin
	 * @date 2013-6-9
	 */	
	public class DragDropManager extends EventDispatcher{
		
		private static var _instance:DragDropManager;
		public static function getInstance():DragDropManager{
			if(!_instance) _instance = new DragDropManager();
			return _instance;
		}
		
		private var _stage:Stage;
		private var _tipsLayer:DisplayObjectContainer;
		private var _curDrager:IDrag;
		private var _curOverContainer:IDragContainer;
		private var _dragedSp:Sprite;
		private var _preDrager:IDrag;
		
		public function DragDropManager(){
			_dragedSp = new Sprite();
			_dragedSp.mouseChildren = false;
			_dragedSp.mouseEnabled = false;
		}
		
		public function registerTipsLayer(layer:DisplayObjectContainer):void
		{
			_tipsLayer = layer;
		}
		
		public function registerStage(stage:Stage):void{
			this._stage = stage;
		}
		
		public function get curDrager():IDrag{ return _curDrager; }
		private function setCurDrager(value:IDrag):void{
			if(_curDrager != value){
				_curDrager = value;
				dispatchEvent(new DragEvent(DragEvent.DRAG_MANAGER_CURDRAGER_CHANGED, _curDrager));
			}
		}
		
		public function get curOverContainer():IDragContainer { return _curOverContainer; }
		
		public function registerIDrager(drager:IDrag):void{
			if(!drager) throw new Error("drager 不是 IDrag,或为null对象");
			drager.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
			drager.addEventListener(MouseEvent.MOUSE_UP, onUp);
		}
		
		public function unregisterIDrager(drager:IDrag):void{
			if(!drager) throw new Error("drager 不是 IDrag,或为null对象");
			drager.removeEventListener(MouseEvent.MOUSE_DOWN, onDown);
			drager.removeEventListener(MouseEvent.MOUSE_UP, onUp);
		}
		
		public function registerIDragerContainer(container:IDragContainer):void{
			if(!container) throw new Error("container 不是 IDragContainer,或为null对象");
			var dspCon:DisplayObjectContainer = container as DisplayObjectContainer;
			if(!dspCon) throw new Error("IDragerContainer必须是个DisplayObjectContainer容器对象");
			container.addEventListener(MouseEvent.ROLL_OVER, onContainerOver);
			container.addEventListener(MouseEvent.ROLL_OUT, onContainerOut);
		}
		
		public function unregisterIDragerContainer(container:IDragContainer):void{
			if(!container) throw new Error("container 不是 IDragContainer,或为null对象");
			container.removeEventListener(MouseEvent.ROLL_OVER, onContainerOver);
			container.removeEventListener(MouseEvent.ROLL_OUT, onContainerOut);
		}
		
		private function onContainerOut(e:MouseEvent):void{
			if(!e) return;
			var container:IDragContainer = e.currentTarget as IDragContainer;
			if(!container) return;
			if(!_curDrager) return;
			container.onDragOut(_curDrager);
			_curOverContainer = null;
		}
		
		private function onContainerOver(e:MouseEvent):void{
			if(!e) return;
			var container:IDragContainer = e.currentTarget as IDragContainer;
			if(!container || !_curDrager) return;
			_curOverContainer = container;
			container.onDragOver(_curDrager);
		}
		
		private function onStageUp(e:MouseEvent):void{
			stopDrag(_curDrager);
		}
		
		private function onUp(e:MouseEvent):void{
			_stage.removeEventListener(MouseEvent.MOUSE_MOVE, onStageMouseMove);
		}
		
		private function onDown(e:MouseEvent):void{
			var drager:IDrag = e.currentTarget as IDrag;
			if(!drager.canDrag) return;
			_preDrager = (e.currentTarget as IDrag);
			_stage.addEventListener(MouseEvent.MOUSE_MOVE, onStageMouseMove);
		}
		
		private function onStageMouseMove(e:MouseEvent):void{
			if(_preDrager) {
				_curDrager = _preDrager;
			}
			if(!_curDrager) return;
			
			startDrag(_curDrager);
		}
		
		public function startDrag(drager:IDrag):void
		{
			_stage.removeEventListener(MouseEvent.MOUSE_MOVE, onStageMouseMove);
			
			if(!drager || !drager.canDrag) return;
			_curDrager = drager;
			var dsp:DisplayObject = _curDrager.getOnDragingDsp();
			dsp.x = -(dsp.width >> 1);
			dsp.y = -(dsp.height >> 1);
			_dragedSp.addChild(dsp);
			_dragedSp.startDrag(true);
			drager.onDragStartedHandler();
			_stage.addEventListener(MouseEvent.MOUSE_UP, onStageUp);
			dsp.alpha = .5;
			if(!_dragedSp.parent){
				if(!_tipsLayer) _tipsLayer = _stage;
				_tipsLayer.addChild(_dragedSp);
			}
		}
		
		public function stopDrag(drager:IDrag):void
		{
			_stage.removeEventListener(MouseEvent.MOUSE_UP, onStageUp);
			
			if(!_curDrager) return;
			_dragedSp.stopDrag();
			DisplayUtil.removeFromParent(_dragedSp);
			DisplayUtil.removeFromParent(_curDrager.getOnDragingDsp());
			if(_curOverContainer){
				_curOverContainer.onDragDrop(_curDrager);//执行
			}
			_curDrager.onDragEndedHandler();
			_preDrager = null;
			_curOverContainer = null;
			setCurDrager(null);
		}
	}
}



// 置于:物品的移动还是交换,还是其它的处理,都得自己在:IDragContainer的实现接口中处理;


简单说明实现流程,CSDN的回复贴内容太多限制,数字才300百多就不可以回复了;

所以写在这吧:

将你的可拖动的类实现IDrag,如:
class BagItem : IDrag
可作为容器的类实现:IDragContainer,如:
class BagItemContainer : IDragContainer
再把BagItem、BagItemContainer分别的实例注册到DragDropManager管理:
var bagItem:BagItem = new BagItem();
var container:BagItemContainer = new BagItemContainer();
DragDropManager.instance.registerIDrager(bagItem);
DragDropManager.instance.registerIDragerContainer(container);

注册代码实例可以写在对应的类的构造函数时处理,比较方式,在dispose时,记得取消注册
DragDropManager.instance.unregisterIDrager
DragDropManager.instance.unregisterIDragerContainer

(旧版的文章,暂时没使用markDown,后面再改吧)

你可能感兴趣的:(AS3 DragManager ---- 自己写个拖动管理器)