CocosCreator封裝搖桿 搖桿控制角色移動 絕對好用(如何使用 + 原理講解)

2020-10-17 17:00:17

原始碼獲取方式在最下面
先看效果
在這裡插入圖片描述

本文分為兩個部分

如何使用
原理講解

如何使用

一共需要四個節點

  • bg:作為背景

在這裡插入圖片描述

  • joystick:作為搖桿的點

在這裡插入圖片描述

  • player:角色(我這裡拿一個小坦克當角色,因為坦克可以更直觀的觀察角色的旋轉)

在這裡插入圖片描述

  • parent:作為搖桿(joystick)和背景(bg)的父節點 這是一個空節點,我們就把指令碼掛在這個節點上

寫指令碼
先來介紹下屬性(不包括剛剛說的那四個節點)

  • max_R
    型別是 number
    搖桿移動的最大半徑

  • speed
    型別是 number
    玩家移動速度
    不建議太大,1-10最好

  • rotation
    型別是 number
    玩家的旋轉角度

  • vector
    型別是cc.Vec2
    移動向量,通過修改這個平面向量來控制角色的移動

  • is_rotation
    型別是 Boolean
    角色是否根據搖桿的方向旋轉

  • is_forbidden
    型別是 Boolean
    是否禁用搖桿
    禁用後搖桿將不能使用

新建一個指令碼,把下面的程式碼複製貼上到裡面

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {

    @property(cc.Node)
    bg: cc.Node = null;//搖桿背景

    @property(cc.Node)
    joystick: cc.Node = null;//搖桿 也就是中心點

    @property(cc.Node)
    player: cc.Node = null;//角色

    @property(cc.Node)
    parent: cc.Node = null;//搖桿和背景的父節點

    @property
    max_R: number = 135;//搖桿移動的最大半徑

    @property
    speed: number = 10;//角色移動速度
    //不建議太大,1-10最好

    @property
    rotation: number = 0;//角色的旋轉角度 不要輕易改

    @property
    vector: cc.Vec2 = cc.v2(0,0);//移動向量

    @property
    is_rotation: boolean = true;//角色是否根據搖桿的方向旋轉

    @property
    is_forbidden: boolean = false;//是否禁用搖桿

    onLoad(){
        //繫結事件
        //因為搖桿很小,如果給搖桿繫結事件玩家將很難控制,搖桿的背景比較大,所以把事件都繫結在背景上是不錯的選擇
        this.bg.on(cc.Node.EventType.TOUCH_MOVE,this.move,this);//當手指在背景上移動時觸發move事件
        this.bg.on(cc.Node.EventType.TOUCH_MOVE,this.move_palyer,this);//當手指在背景上移動時觸發move_player事件
        this.bg.on(cc.Node.EventType.TOUCH_END,this.finish,this);//當手指在目標節點區域內離開螢幕時觸發finish事件
        this.bg.on(cc.Node.EventType.TOUCH_CANCEL,this.finish,this);//當手指在目標節點區域外離開螢幕時觸發finish事件
    }

    update(){
        let x = this.player.x + this.vector.x;
        let y = this.player.y + this.vector.y;//每幀獲取角色的座標加上移動向量

        this.player.position = cc.v3(x, y);//讓角色的座標每幀為自身的座標加上移動的向量
        
        //求出角色的旋轉角度
        if(this.vector.y < 0){//當搖桿在原點下方時
            //角度是負的
            this.rotation = (-this.vector.angle(cc.v2(1, 0))) / Math.PI * 180;//根據向量先求出弧度,再求出角度
        }else{//如果搖桿在原點上方時
            //角度是正的
            this.rotation = (this.vector.angle(cc.v2(1, 0))) / Math.PI * 180;//根據向量先求出弧度,再求出角度
        }
    }

    move(event: cc.Event.EventTouch){//負責移動搖桿 手指移動時呼叫
        if(this.is_forbidden == false){//如果沒有禁用搖桿
            let pos = new cc.Vec2(event.getLocationX(), event.getLocationY());//獲取觸點的座標
            let pos_0 = this.parent.convertToNodeSpaceAR(pos);//將一個點轉換到節點 (區域性) 空間座標系,這個座標系以錨點為原點。

            //pos_0.mag()是這個觸點的長度

            if(pos_0.mag() < this.max_R){//如果觸點長度小於我們規定好的最大半徑
                this.joystick.x = pos_0.x;//搖桿的座標為觸點座標
                this.joystick.y = pos_0.y;
            }else{//如果不
                let pos = pos_0.normalizeSelf();//將觸點歸一化
                let x = pos.x * this.max_R;//歸一化的觸點座標 × 最大半徑
                let y = pos.y * this.max_R;

                this.joystick.x = x;//給搖桿座標賦值
                this.joystick.y = y;
            }    
        }
    }

    move_palyer(){//負責移動角色 手指移動時呼叫
        if(this.is_forbidden == false){//如果沒有禁用搖桿
            let dir = this.joystick.position.normalizeSelf();//dir為搖桿座標的歸一化

            this.vector.x = dir.x * this.speed;//給移動向量賦值
            this.vector.y = dir.y * this.speed;//移動向量為方向 × 速度
            if(this.is_rotation == true){//如果角色可以旋轉
                this.player.angle = this.rotation;//根據搖桿的方向旋轉角色
            }
        }
    }

    finish(){//搖桿彈回原位置
        //搖桿座標和移動向量都為(0,0)
        this.joystick.position = cc.v3(0, 0);
        this.vector = cc.v2(0, 0);
    }

}

繫結好節點
在這裡插入圖片描述

原理講解

每句程式碼我都寫了詳細的註釋哦

先來實現搖桿的移動
在這裡插入圖片描述
這就是表現上的內容,在拉動搖桿的時候角色並沒有動,只是搖桿在動,先來實現這個

需要給背景繫結事件,其實應該給搖桿繫結事件,因為搖桿很小,如果給搖桿繫結事件玩家將很難控制,搖桿的背景比較大,所以把事件都繫結在背景上是不錯的選擇
在這裡插入圖片描述
這就是給背景繫結的事件,當手指在背景上移動時觸發

首先獲取觸點座標,轉化為parent節點區域性空間座標系
我們只希望搖桿在規定好的max_R(最大半徑)的範圍內,不希望搖桿超出這個範圍
所以要判定一下觸點的座標在不在我們制定的最大半徑範圍內,通過mag獲取觸點座標的長度,也就是觸點距離原點的長度
在這裡插入圖片描述
比如我想求點A座標的長度,求出的結果就是綠色線段的長度

再來實現功能內容(控制角色移動)
在這裡插入圖片描述
把搖桿的座標歸一化,然後 × 速度,賦值給vector,如果可以旋轉還要讓角色旋轉

update
在這裡插入圖片描述
根據vector求出夾角弧度,再求出角度,判斷角度正負
公式
角度轉弧度 π/180×角度
弧度變角度 180/π×弧度

最後一定要在鬆開搖桿時讓搖桿彈回原處
在這裡插入圖片描述
原始碼在群裡面
Cocos技術交流Q群:1130122408
歡迎進群閒聊、技術交流都歡迎
製作不易,感謝你的觀看
Thank You~~