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