图片拖拽效果

游戏中比较常见的拖拽效果,例如拖动技能icon或者其他道具icon到指定位置,松开之后,判断能否使用。

下面是用laya与as3实现拖拽效果的代码(需求是拖拽icon,并且,icon拖拽道具到指定位置时如果满足条件,该指定位置的item高亮显示)

先在UI编辑器里面给各个item添加name,博主这里假设icon只有2个,并给name分别赋值为icon0,icon1,对此,单纯的拖拽和松开鼠标时进行判断已经满足不了需求了,还需添加黑色背景。而黑色背景是一个封装接口,与UI显示层级是并列的,无法通过调整层级实现高亮,故只能直接在stage上添加item来实现高亮效果。item为new的添加在stage上的icon。icon0和icon1为原本就应该显示的icon

//定义将要添加在stage的item,Class视具体情况定义为指定的变量类型
private var item:dragClass;
private var cloneIconItem:iconClass;
//黑色半透明背景遮罩
private var blackMask:blackMaskClass;
private var _dragImage:Image;
//有需求要给stage添加item,那么必定存在remove item的过程
//从stage移除添加在stage上的item,这里注意,如果直接在stage上添加,
//因为原位置还存在本来就有的item,会出现重叠(表现上就是字体颜色较浓等等,故判断可以高亮显示时,
//隐藏原位置的item,那么移除添加在stage上的item时,就需要将显示出原位置的icon)
private function removeAllItem():void{
    for(var i:int = 0;i<2;i++){
        this["icon"+i].visible = true;
    }
    item&&item.removeSelf();
    cloneIconItem&&cloneIconItem.removeSelf();
}

//满足条件时给stage添加item
private function addItem():void{
    var p:Point;
    //数据源数据类型
    var data:*;
    for(var i:int = 0;i<2;i++){
        if(满足指定条件){
            cloneIconItem = new iconClass();
            cloneIconItem.dataSource = this["icon"+i].dataSource;
            this["icon"+I].visible = false;
            //因为是直接添加在stage上,所以这里需要对坐标和缩放进行全局转化
            p = this["icon"+i].localToGlobal(new Point(0,0),true);
            cloneIconItem.scale(this["icon"+i].globalScaleX,this["icon"+I].scaleY);
            cloneIconItem.pos(p.x,p.y);
            this["icon"+I].zOrder = 999;
            Laya.stage.addChild(cloneIconItem);
            break;
        }
    }
}

//鼠标在可拖拽对象上按下时,显示拖拽对象并显示黑色半透明背景
private function onMouseDown(e:Event):void{
    var downItem:objClass = e.currentTarget as objClass;
    //如果点击位置不是数据渲染对象,直接return
    if(!downItem.dataSource){
        return;
    }
    //显示拖拽icon
    _dragImage = showDragImage(item);
    //添加监听,注意这里是鼠标按下之后才添加拖拽相关监听,而不是打开界面直接添加拖拽监听
    Laya.stage.on(Event.MOUSE_UP,this,onMouseUp);
    Laya.stage.on(Event.MOUSE_OUT,this,onMouseOut);
    Laya.stage.on(Event.MOUSE_MOVE,this,onMouseMove);
    addItem();
}

//new一个可跟随鼠标移动的icon(可拖拽icon)或者清除stage上的可拖拽icon
private function showDragImage(item:dragClass, drag:Boolean = true):Image{
    if(!_dragImage){
        _dragImage = new Image();
    }
    _dramImage.mouseEnabled = false;
    _dragImage.size(item.icon.width,item.icon.height);
    _dragImage.zOrder = 1000;
    //设置_dragImage的中心点为鼠标所在位置
    _dragImage.x = Laya.stage.mouseX - _dragImage.width/2;
    _dragImage.y = Laya.stage.mouseY - _dragImage.height/2;
    if(drag){
    //给stage添加拖拽icon
        blackMask&&blackMasc.removeSelf();
        black = new blackMaskClass();
        black.alpha = 0.5;
        blackMask.mouseEnabled = false;
        //注意这里blackMask的zOrder足够大,但是比item和_dragImage的zOrder都小
        blackMask.zOrder  = 998;
        Laya.stage.addChild(blackMask);
    }else{
    //从stage移除拖拽icon
        blackMask&&blackMask.removeSelf();
        _dragImage&&_dragImage.removeSelf();
        removeAllItem();
    }
    return _dragImage;
}

//下面鼠标按下之后,对应的三个事件监听的处理
//移动鼠标(拖拽icon)
private function onMouseMove(e:Event):void{
    _dragImage.x = Laya.stage.mouseX - _dragImage.width/2;
    _dragImage.y = Laya.stage.mouseY - _dragImage.height/2;
    var targetItem:* = e.target;
    //无限向上寻找父级元素
 //直到父级元素是想要与拖拽item碰撞后进行判断的元素或者没有父级(最多为stage,stage无父级元素)
     while(!targetItem is iconClass && !targetItem is dragClass && targetItem.parent){
        if(targetItem.parent){
            targetItem = targetItem.parent;
        }else{
   //一直向上寻找父级,最终也没找到满足条件的父级元素,理论上不应该出现这种情况,避免报错,兼容处理
            removeAllItem();
        }
    }
}

//鼠标从stage移到stage外时
private function onMouseOut(e:Event):void{
    if(e.currentTarget !=Laya.stage){
        return;
    }
    showDragImage(null, false);
    Laya.stage.off(Event.MOUSE_UP,this,onMouseUp);
    Laya.stage.off(Event.MOUSE_OUT,this,onMouseOut);
    Laya.stage.off(Event.MOUSE_MOVE,this,onMouseMove);
}

//松开鼠标时,如果已经碰撞了,则判断是否满足指定条件执行相应操作,
//否则直接移除监听,移除stage添加的临时添加的_dragImage、blackMask等
private function onMouseUp(e:Event):void{
    showDragImage(null, false);
    Laya.stage.off(Event.MOUSE_UP,this,onMouseUp);
    Laya.stage.off(Event.MOUSE_OUT,this,onMouseOut);
    Laya.stage.off(Event.MOUSE_MOVE,this,onMouseMove);
        var targetItem:* = e.target;
    //无限向上寻找父级元素
 //直到父级元素是想要与拖拽item碰撞后进行判断的元素或者没有父级(最多为stage,stage无父级元素)
     while(!targetItem is iconClass && !targetItem is dragClass && targetItem.parent){
        if(targetItem.parent){
            targetItem = targetItem.parent;
        }else{
   //一直向上寻找父级,最终也没找到满足条件的父级元素,理论上不应该出现这种情况,避免报错,兼容处理
            removeAllItem();
        }
    }
    //如果不是碰撞对象,直接return,没有后续操作了
    if(!targetItem is iconClass){
        return;
    }
    //如果时碰撞检测对象,则判断条件是否满足,满足则执行相应代码
    if(满足某指定条件){
        console.log("执行相应代码");
    }
}
发布了61 篇原创文章 · 获赞 2 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_22794043/article/details/88672193