1. 程式人生 > >CreatorPrimer|可拖拽元件

CreatorPrimer|可拖拽元件

在遊戲中實現節點的可拖動是一個比較常見情況,比如:可以給小朋友做一個將果皮投進垃圾箱的教學練習、角色換裝、物品包裹介面等。在Cocos Creator中實現一個可拖動元件,只需對目標節點拖拽配置就能讓節點任意移動,這對策劃、美術人員來說是不是很有殺傷力!

1. 建立測試場景

在實現一個元件程式碼之前最好新建一個測試場景,元件程式碼在測試場景中通過了基本測試之後再放入正式環境使用。而且在元件完成後,測試場景最好也不要丟棄了,等我們以後為元件升級或修改BUG時,可用於快速檢驗修改是否正確。
初始化工程

2. 實現可拖拽元件

我們來看下元件程式碼非常簡單,就算你不會程式設計,根著註釋相信也能明白個大概:

cc.Class({
    extends: cc.Component,

    onLoad() {
        //註冊TOUCH_MOVE事件
        this.node.on(cc.Node.EventType.TOUCH_MOVE, this._onTouchMove, this);
    },

    _onTouchMove(touchEvent) {
        //通過touchEvent獲取當前觸控座標點
        let location = touchEvent.getLocation();
        //將觸控座標點轉換為要移動的節點所在容器節點的座標
        this.node.position = this.node.parent.convertToNodeSpaceAR(location);
    }
});

Markdwon下始終沒成功插入視訊,還請有經驗的朋友指點,感謝!

3. 設定移動目標

有了這個元件,可以控制節點任意移動了,但是很多情況下,需要將節點移動到指定位置,比如將果皮投進垃圾箱,我們增強一下元件程式碼:

cc.Class({
    extends: cc.Component,

    properties: {
        target: cc.Node,
    },

    onLoad() {
        //快取原始父節點
        this._oldPosition = this.node.position;
       
        this.node.on(cc.Node.EventType.TOUCH_MOVE, this._onTouchMove, this);
        this.node.on(cc.Node.EventType.TOUCH_END, this._onTouchEnd, this);
    },

    _onTouchMove(touchEvent) {
        let location = touchEvent.getLocation();
        this.node.position = this.node.parent.convertToNodeSpaceAR(location);
    },

    _onTouchEnd(touchEvent) {
        if (!this.target) {
            return;
        }
        //獲取target節點在父容器的包圍盒,返回一個矩形物件
        let rect = this.target.getBoundingBox();
        //使用target容器轉換觸控座標
        let location = touchEvent.getLocation();
        let point = this.target.parent.convertToNodeSpaceAR(location);
        //if (cc.rectContainsPoint(rect, targetPoint)) {
        //Creator2.0使用rect的成員contains方法
        if (rect.contains(point)) {
            //在目標矩形內,修改節點座標  
            point = this.target.convertToNodeSpaceAR(location); 
            this.node.position = point;
            //修改父節點 
            this.node.parent = this.target;
            return;
        }
        //不在矩形中,還原節點位置    
        this.node.position = this._oldPosition;
    }
});

程式碼變複雜了,簡單說明一下:

  1. 是增加了一個target節點屬性,他是節點要移動到的目標
  2. 增加TOUCH_END事件,當手指擡起時,檢查當前節點是否在目標節點之中
  3. 在目標範圍,修改節點父子關係
  4. 不在目標範圍,還原節點位置(提前快取節點原始座標)

元件有了鎖定目標的功能,現在就可以實現將果皮投進垃圾箱了,當然也可以用來實現給角色換裝、物品包裹之類的操作,請看下面的演示:
增強可拖動元件

Markdwon下始終沒成功插入視訊,還請有經驗的朋友指點,感謝!
我給目標節點掛載了一個Layout元件,設定成GRID模式,實現自動網格排列,很像遊戲中的物品包裹功能,這個元件真的是物超所值哦!

4. 小結

這次主要運用了節點的觸控事件監聽,在觸控事件的touchEvent引數中獲取當前觸控座標點。同時還需要對座標點在不同節點座標系下進行轉換,需要理解的是拖動節點的本質是:修改節點在父節點上的位置,需要使用this.node.parent.convertToNodeSpaceAR進行轉換。同時還有使用了最簡單的碰撞檢測函式rect.contains(在Cocos Creator 1.9.3之前用cc.rectContainsPoint),檢查一個座標點是否在矩形內。

好了這次的程式碼有點多非程式設計師同學要好好消化下,發揮你的想像,可以使用這個元件做出更有趣的東西。

歡迎關注「奎特爾星球」微信公眾號,來我們一起成長!

「奎特爾星球」