这个是自己为当前需求而写的一个拖动管理器;
比较轻量级,没有mx类库下的DragManager那么强大;
一般用于web game的各种拖动处理的话,够用了:
执行效果,如图:
目前我们只能定义成,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; } }
这里最要处理一些拖动的流程代码:
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,后面再改吧)