这个是自己为当前需求而写的一个拖动管理器;
比较轻量级,没有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;
}
}
最后是我们的主角: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,后面再改吧)