自定義虛擬搖桿元件讓你一勞永逸
阿新 • • 發佈:2019-09-04
最近在研究虛擬搖桿實現方式的時候,發現網上的教程的實現方式可移植性並不是特別好,於是我決定自己實現一個虛擬搖桿元件,儲存到自己的元件庫,方便以後用到的時候直接使用(關注公眾號後臺回覆「虛擬搖桿元件」可獲取該元件),下面正文開始。
實現思路:
為了實現高度可移植,定義了兩個節點屬性,用於繫結場景和玩家角色,另外新增 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於」,立志做一個每天都有正反饋的人!