《Cocos Creator遊戲實戰》手勢縮放功能實現

手勢縮放功能實現

創建節點

編寫腳本


在這篇教程中我們來實現一個手勢縮放功能。

運行效果如下:

 

Cocos Creator版本:2.2.0

後臺回覆"手勢縮放",獲取該項目完整文件:

 

創建節點

層級管理器中我們只創建了兩個節點:

1. maskNode爲空節點,不過我們在上面加了一個mask組件用於遮罩。

2. luffy節點就是一張圖片(海賊王路飛圖)。

 

maskNode和luffy節點大小一樣(也就是說圖片正好完全顯示):

 

編寫腳本

創建一個Zoom.js腳本,將該腳本掛到Canvas節點上。

現在在properties中添加如下屬性:

// Zoom.js
properties: {
    maskNode: cc.Node,
    picNode: cc.Node,
},

然後在onLoad方法中添加觸摸監聽相關代碼:

// Zoom.js
onLoad () {
    // 觸摸監聽
    this.node.on('touchstart', this.onTouchStart, this);
    this.node.on('touchmove', this.onTouchMove, this);
},

onTouchStart方法編寫如下:

// Zoom.js
onTouchStart (event) {
    let touches = event.getTouches();
    if (touches.length == 1) {
        // 一根手指是移動,這裏不用寫任何代碼       
    }
    else if (touches.length == 2) {
        this.startPos1 = this.node.convertToNodeSpaceAR(touches[0].getLocation());
        this.startPos2 = this.node.convertToNodeSpaceAR(touches[1].getLocation());
        this.pointsDis = this.startPos1.sub(this.startPos2).mag();
    }
}, 

在該方法中我們判斷玩家使用的是一根手指還是多根。一根表明只是移動圖片,兩根手指表明是縮放圖片。當手指數量等於1時,我們這裏其實不用做什麼操作(在onTouchMove方法中會有相關操作代碼);當數量等於2時,我們記錄下手指們的初始座標,並計算出這兩根手指的距離,後續會用到。

 

onTouchMove方法如下:

// Zoom.js
onTouchMove (event) {
    let touches = event.getTouches();
    if (touches.length == 1) {
        // 一根手指是移動
        let delta = event.getDelta();
        this.picNode.setPosition(this.picNode.position.add(delta));
        this.restrictPic();
    }
    else if (touches.length == 2) {
        // 兩根手指是縮放
        let touchPoint1 = this.node.convertToNodeSpaceAR(touches[0].getLocation());
        let touchPoint2 = this.node.convertToNodeSpaceAR(touches[1].getLocation());
        let newPointsDis = touchPoint1.sub(touchPoint2).mag();

        if (newPointsDis > this.pointsDis) {
            // 表明兩根手指在往外劃
            this.pointsDis = newPointsDis;
            this.picNode.scale += 0.05;
        }   
        else if (newPointsDis < this.pointsDis) {
            // 表明兩根手指在往內劃
            if (this.picNode.scale <= 1) {
                this.picNode.scale = 1;
                return;
            }

            this.pointsDis = newPointsDis;
            this.picNode.scale -= 0.05;
        }

        this.restrictPic();
    }
},

若手指數量爲1,我們只用求出手指移動的距離,然後給圖片加上這段距離即可(restrictPic方法用於限制圖片移動,防止出現黑邊,這個我們在最後會講)。若手指數量爲2,我們求出兩根手指移動後的新距離,如果該新距離newPointsDis大於初始距離pointsDis,也就是說兩根手指在往外劃(因爲手指間的距離在變大),那麼玩家就是想要放大圖片。而如果新距離newPointsDis小於初始距離pointsDis,則表明玩家想要縮小圖片,但要注意圖片scale值最小爲1。

放大

縮小

 

最後我們來看下restrictPic方法:

// Zoom.js
restrictPic () {
    // 限制移動,放置出現黑邊
    let picWidth = this.picNode.getBoundingBox().width;
    let picHeight = this.picNode.getBoundingBox().height;
    if (this.picNode.x>0 && this.picNode.x-0>picWidth/2-this.maskNode.width/2)
        this.picNode.x = picWidth/2-this.maskNode.width/2;
    if (this.picNode.x<0 && this.picNode.x-0<this.maskNode.width/2-picWidth/2)
        this.picNode.x = this.maskNode.width/2-picWidth/2;
    if (this.picNode.y>0 && this.picNode.y-0>picHeight/2-this.maskNode.height/2)
        this.picNode.y = picHeight/2-this.maskNode.height/2;
    if (this.picNode.y<0 && this.picNode.y-0<this.maskNode.height/2-picHeight/2)
        this.picNode.y = this.maskNode.height/2-picHeight/2;
}

注:改變節點的scale值並不會改變節點width和height的實際值。如果要獲取節點縮放後能夠影響碰撞的width和height值,我們需要調用getBoundingBox方法。

爲方便理解以上代碼,請大家看下圖:

藍色框爲picNode,紅色框爲maskNode,這裏picNode大於maskNode表示玩家已經進行了放大操作。綠點爲中心原點(0, 0)。

從圖片可以看出,如果向右移動,爲了不讓畫面出現黑邊,picNode移動的最大距離就是picWidth/2-this.maskNode.width/2。如果一旦超出,那我們就讓picNode的x座標值等於picWidth/2-this.maskNode.width/2。

向左向上和向下移動時同理。

 

好了,本期就成就到此爲止,希望大家有所收穫~

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