拖動水滴給土地澆水(CocosCreator)

推薦閱讀:

一。前沿

      最近在做農場的模塊,需要實現拖動水滴圖標(💧)到土地上,對某個土地澆水。研究了一天,上網找了各大博客的文章,也沒有找到類似的文章,又去找了一些農場的demo,也沒有該功能的實現。終於,皇天不負有心人,在與一些大佬的聊天中,我找到了突破口,然後一步一步,實現了該功能。現在懷着喜悅的心情來和大家分享一下成果。

二。思路

1。首先要實現的是拖動水滴(💧),使水滴(💧)隨着鼠標的移動而移動。這一步驟可以分爲三個階段:
   (1)鼠標按下:在水滴圖標處按下鼠標
   (2)鼠標按住不放移動:在(1)的基礎上,保持鼠標按下的狀態移動,同步水滴位置。
   (3)鼠標擡起:判斷是否可澆水(即擡起鼠標時水滴是否在某塊土地上)
2。如何檢測上面的步驟(3)時,是否能進行澆水,這裏介紹最常用也是最簡單的方法:碰撞檢測。

三。步驟

1。拖動水滴(💧),移動位置,這裏需要1個標誌位(即布爾值),標誌鼠標的按下與擡起。用於下問中判斷是否可以執行碰撞檢測,因爲只有在鼠標擡起的時候才需要執行碰撞檢測。
如果你的農場本身是一個ScrollView做的可滑動的界面,那麼你需要在鼠標按下選中水滴(💧)的時候,將滑動關閉,在鼠標擡起時,開啓滑動。

		//拖動水滴
        uiRoot.goWater = cc.find("goWater", obj1);
        uiRoot.goWater.on(cc.Node.EventType.MOUSE_DOWN, (event) => {
            self.mouseDown = true;
            self.uiRoot.BgScrollView.enabled=false;//關閉滑動
        });
        uiRoot.goWater.on(cc.Node.EventType.MOUSE_MOVE, (event) => {
            if (!self.mouseDown) { return; }
            //獲取鼠標距離上一次點的信息
            let delta = event.getDelta();
            //移動水滴
            uiRoot.goWater.x = uiRoot.goWater.x + delta.x;
            uiRoot.goWater.y = uiRoot.goWater.y + delta.y;
        });
        uiRoot.goWater.on(cc.Node.EventType.MOUSE_UP, (event) => {
            self.mouseDown = false;
            self.uiRoot.BgScrollView.enabled=true;/開啓滑動
            self.uiRoot.goWater.setPosition(self.waterPos[0], self.waterPos[1]);//鼠標鬆開,水滴回到原來的UI處的位置
        });

上面提到了碰撞檢測,下面先介紹碰撞檢測的步驟:

(1)將需要檢測的區域或者節點添加碰撞器,碰撞器的類型有三種:
   a.方形碰撞器:Box Collider
   b.圓形碰撞器:Circle Collider
   c.多邊形碰撞器:Polygon Collider
(上面三種碰撞器除了形狀不同之外,用法及屬性等都一樣。)
由於這裏的土地時方形的,所以我選擇了Box Collider碰撞器,需要注意的是,不僅要給土地添加碰撞器,還需要給水滴添加碰撞器,因爲碰撞肯定是兩個及以上物體纔會發生的。
Box Collider有個Tag屬性,即標籤,用於標識是哪個節點,爲了方便,在代碼中我們會把所有土地存儲在一個數組裏面,把每個土地在數組中的下標值作爲該土地的Tag值,這樣在後面碰撞檢測中可以通過獲取到的Tag值,直接通過數組映射到對應的土地上。

(2)對物體進行分組,即指定節點的分組與分組的碰撞矩陣
a、查看和添加分組:項目——>項目設置——>分組管理裏面進行設定在這裏插入圖片描述
b、添加分組(注意添加一個分組,裏面有對應的序號和名字)在這裏插入圖片描述
c、指定節點的分組與分組的碰撞矩陣,如下圖在這裏插入圖片描述
(3)由於cocos默認碰撞檢測是關閉的,因此需要自己開啓,開啓和關閉碰撞檢測的調試開啓方法:

   var manager=cc.director.getCollisionManager(); // 獲取碰撞檢測類

   manager.enabled=true //開啓碰撞檢測

   manager.enabledDebugDraw=true //顯示碰撞檢測區域

cc.Class({
    extends: cc.Component,

    properties: {
        isEnable: true,    //是否開啓碰撞檢測系統
        isDebug: true//是否顯示碰撞檢測區域
    },
    
    onLoad() {
        if (this.isEnable) {
            let manager = cc.director.getCollisionManager();// 獲取碰撞檢測類
            manager.enabled = true;     //開啓碰撞檢測
            if (this.isDebug) {
                manager.enabledDebugDraw = true;   //顯示碰撞檢測區域
            }
        }
    }
});

(4)新建一個專門用於碰撞檢測的js腳本,該腳本主要調用了引擎自帶的碰撞檢測的三個回調函數:

onCollisionEnter:function(other,self){} => 當兩物體剛發生碰撞時被觸發

onCollisionStay:function(other,self){} => 當兩物體發生碰撞後,並且有交集的時候被觸發

onCollisionExit:function(other,self){} => 當兩物體發生碰撞後,並且在離開的那一刻被觸發

    onCollisionExit(other, self) {
        // console.log('現在剛離開')
        if (!gm.FramLayer.mouseDown) {
        	//other.tag土地標籤
            gm.FramLayer.waterArr[other.tag].active = true;//顯示澆水標誌
        }
    }

      other.tag是上面提及到的土地的Tag,也是某土地在土地數組中的下標值。

      將該腳本綁定在佔據主導地位的碰撞檢測的節點上(此案例中即水滴)。這時候可能會有疑問了,佔據主導地位的節點?這個來解釋呢?所謂的佔據主導地位是指,我具有主動權,我可以決定碰撞另一個組或另幾個組中任意一個或幾個節點。在這個案例中可以理解爲:水滴(💧)作爲圖標,可以移動位置,而土地的位置固定不動,他只能被其他帶有碰撞器的節點碰撞。通俗的理解,可以理解爲主動與被動的關係。

至此,就實現了我們開始所說的,拖動水滴圖標到某土地上,實現澆水功能。

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