1. 程式人生 > >自定義虛擬搖桿元件讓你一勞永逸

自定義虛擬搖桿元件讓你一勞永逸

最近在研究虛擬搖桿實現方式的時候,發現網上的教程的實現方式可移植性並不是特別好,於是我決定自己實現一個虛擬搖桿元件,儲存到自己的元件庫,方便以後用到的時候直接使用(關注公眾號後臺回覆「虛擬搖桿元件」可獲取該元件),下面正文開始。

 

實現思路:

為了實現高度可移植,定義了兩個節點屬性,用於繫結場景和玩家角色,另外新增 PlayerNodeSpeed 屬性和 MaxR 屬性用於控制玩家移動速度和搖桿節點的移動範圍。

 

實現過程:

1.首先建立一個空節點 Rocker,下面掛載上虛擬搖桿的背景 rockerBg 和搖桿節點 joystick:

 

2.然後給建立好節點新增合適的虛擬搖桿資源,沒有資源的小夥伴可以關注公眾號後臺回覆「虛擬搖桿」獲取多套美術資源:

 

3.之後編寫指令碼如下,程式碼中已經儘可能詳細做好了備註,如果仍有不清楚的小夥伴可以後臺私信我,看到後我會及時回覆的:

  1 // Rocker.js
  2 
  3 cc.Class({
  4     extends: cc.Component,
  5 
  6     properties: {
  7         sceneNode: {    // 場景節點
  8             type: cc.Node,
  9             default: null,
 10         },
 11 
 12         playerNode: {    // player節點
 13             type: cc.Node,
 14             default: null,
 15         },
 16 
 17         playerNodeSpeed: 100,    // player移動速度
 18 
 19         Max_r: 100,    // 搖桿移動半徑,根據自己美術資源進行調整
 20     },
 21 
 22     onLoad() {
 23         // 隱藏搖桿元件節點
 24         this.node.active = false;
 25 
 26         // 獲取搖桿節點並初始化搖桿節點位置及角度
 27         this.joystick = this.node.getChildByName('joystick')
 28         this.joystick.setPosition(cc.v2(0, 0));
 29         this.dir = cc.v2(0, 0);
 30 
 31         // 註冊父節點的 touch 監聽事件
 32         this.sceneNode.on(cc.Node.EventType.TOUCH_START, this.cbTouchStart, this);
 33         this.sceneNode.on(cc.Node.EventType.TOUCH_MOVE, this.cbTouchMove, this);
 34         this.sceneNode.on(cc.Node.EventType.TOUCH_END, this.cbTouchEnd, this);
 35         this.sceneNode.on(cc.Node.EventType.TOUCH_CANCEL, this.cbTouchCancel, this);
 36     },
 37 
 38     update(dt) {
 39         if (this.dir.mag() < 0.5) {
 40             return;
 41         }
 42 
 43         let vx = this.dir.x * this.playerNodeSpeed;
 44         let vy = this.dir.y * this.playerNodeSpeed;
 45 
 46         let sx = vx * dt;
 47         let sy = vy * dt;
 48         //移動
 49         this.playerNode.x += sx;
 50         this.playerNode.y += sy;
 51 
 52         let windowsSize = cc.winSize;
 53 
 54         let minX = -windowsSize.width / 2 + this.playerNode.width / 2;    // 最小X座標
 55         let maxX = Math.abs(minX);    // 最大X座標
 56         let minY = -windowsSize.height / 2 + this.playerNode.height / 2;    // 最小Y座標
 57         let maxY = Math.abs(minY);    // 最大Y座標
 58 
 59         let currentPos = this.playerNode.getPosition();
 60 
 61         if (currentPos.x < minX) {
 62             currentPos.x = minX;
 63         } else if (currentPos.x > maxX) {
 64             currentPos.x = maxX;
 65         } 
 66         
 67         if (currentPos.y < minY) {
 68             currentPos.y = minY;
 69         } else if (currentPos.y > maxY) {
 70             currentPos.y = maxY;
 71         }
 72 
 73         this.playerNode.setPosition(currentPos);
 74 
 75         //方向計算
 76         var r = Math.atan2(this.dir.y, this.dir.x);
 77         var degree = r * 180 / (Math.PI);
 78         degree = 360 - degree + 90;
 79         this.playerNode.rotation = degree;
 80     },
 81 
 82     cbTouchStart(event) {
 83         let pos = event.getLocation();
 84 
 85         // 點選時顯示搖桿元件節點並設定位置
 86         this.node.active = true;
 87         let rPos = this.sceneNode.convertToNodeSpaceAR(pos);    // 將世界座標轉化為場景節點的相對座標
 88         this.node.setPosition(rPos);
 89         
 90         // 初始化搖桿節點位置及角度
 91         this.joystick.setPosition(cc.v2(0, 0));
 92         this.dir = cc.v2(0, 0);
 93     },
 94 
 95     cbTouchMove(event) {
 96         var pos = event.getLocation();
 97 
 98         var jPos = this.node.convertToNodeSpaceAR(pos);    // 將世界座標轉化為搖桿元件節點的相對座標
 99 
100         // 獲取搖桿的角度
101         let len = jPos.mag();
102         this.dir.x = jPos.x / len;
103         this.dir.y = jPos.y / len;
104 
105         // 設定搖桿的位置
106         if (len > this.Max_r) {
107             jPos.x = this.Max_r * jPos.x / len;
108             jPos.y = this.Max_r * jPos.y / len;
109         }
110         this.joystick.setPosition(jPos);
111     },
112 
113     cbTouchEnd(event) {
114         // 初始化搖桿節點位置及角度
115         this.joystick.setPosition(cc.v2(0, 0));
116         this.dir = cc.v2(0, 0);
117         this.node.active = false;
118     },
119 
120     cbTouchCancel(event) {
121         // 初始化搖桿節點位置及角度
122         this.joystick.setPosition(cc.v2(0, 0));
123         this.dir = cc.v2(0, 0);
124         this.node.active = false;
125     }
126 });

 

4.最後將寫好的指令碼掛載到 Rocker 節點上儲存為 Prefab 就可以使用了:

 

使用步驟:

1.建立好場景和玩家角色後,將 Rocker 元件拖到場景中,並將 Canvas 和 玩家角色掛載到對應的位置,設定好合適的移動速度和搖桿移動半徑後就可以使用了:

 

2.可以看到已經可以流暢的控制玩家移動了:

 

最後:

不知道小夥伴們學會了沒有,趕快來試試看吧,有什麼好的建議都可以在下面評論或者私信告訴我哦!

 


 

推薦閱讀:

讓蔡徐坤來教你實現遊戲中的幀動畫(上)

讓蔡徐坤來教你實現遊戲中的幀動畫(中)

一文教你實現「飛機大戰」裡戰機的控制邏輯

 


 

我是「Super於」,立志做一個每天都有正反饋的人!