圖片拖拽效果

遊戲中比較常見的拖拽效果,例如拖動技能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("執行相應代碼");
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章