最近在研究虛拟搖杆實作方式的時候,發現網上的教程的實作方式可移植性并不是特别好,于是我決定自己實作一個虛拟搖杆元件,儲存到自己的元件庫,友善以後用到的時候直接使用(關注公衆号背景回複「虛拟搖杆元件」可擷取該元件),下面正文開始。
實作思路:
為了實作高度可移植,定義了兩個節點屬性,用于綁定場景和玩家角色,另外添加 PlayerNodeSpeed 屬性和 MaxR 屬性用于控制玩家移動速度和搖杆節點的移動範圍。
實作過程:
1.首先建立一個空節點 Rocker,下面挂載上虛拟搖杆的背景 rockerBg 和搖杆節點 joystick:
2.然後給建立好節點添加合适的虛拟搖杆資源,沒有資源的小夥伴可以關注公衆号背景回複「虛拟搖杆」擷取多套美術資源:
3.之後編寫腳本如下,代碼中已經盡可能詳細做好了備注,如果仍有不清楚的小夥伴可以背景私信我,看到後我會及時回複的:
// Rocker.js
cc.Class({
extends: cc.Component,
properties: {
sceneNode: { // 場景節點
type: cc.Node,
default: null,
},
playerNode: { // player節點
type: cc.Node,
default: null,
},
playerNodeSpeed: 100, // player移動速度
Max_r: 100, // 搖杆移動半徑,根據自己美術資源進行調整
},
onLoad() {
// 隐藏搖杆元件節點
this.node.active = false;
// 擷取搖杆節點并初始化搖杆節點位置及角度
this.joystick = this.node.getChildByName('joystick')
this.joystick.setPosition(cc.v2(0, 0));
this.dir = cc.v2(0, 0);
// 注冊父節點的 touch 監聽事件
this.sceneNode.on(cc.Node.EventType.TOUCH_START, this.cbTouchStart, this);
this.sceneNode.on(cc.Node.EventType.TOUCH_MOVE, this.cbTouchMove, this);
this.sceneNode.on(cc.Node.EventType.TOUCH_END, this.cbTouchEnd, this);
this.sceneNode.on(cc.Node.EventType.TOUCH_CANCEL, this.cbTouchCancel, this);
},
update(dt) {
if (this.dir.mag() < 0.5) {
return;
}
let vx = this.dir.x * this.playerNodeSpeed;
let vy = this.dir.y * this.playerNodeSpeed;
let sx = vx * dt;
let sy = vy * dt;
//移動
this.playerNode.x += sx;
this.playerNode.y += sy;
let windowsSize = cc.winSize;
let minX = -windowsSize.width / 2 + this.playerNode.width / 2; // 最小X坐标
let maxX = Math.abs(minX); // 最大X坐标
let minY = -windowsSize.height / 2 + this.playerNode.height / 2; // 最小Y坐标
let maxY = Math.abs(minY); // 最大Y坐标
let currentPos = this.playerNode.getPosition();
if (currentPos.x < minX) {
currentPos.x = minX;
} else if (currentPos.x > maxX) {
currentPos.x = maxX;
}
if (currentPos.y < minY) {
currentPos.y = minY;
} else if (currentPos.y > maxY) {
currentPos.y = maxY;
}
this.playerNode.setPosition(currentPos);
//方向計算
var r = Math.atan2(this.dir.y, this.dir.x);
var degree = r * 180 / (Math.PI);
degree = 360 - degree + 90;
this.playerNode.rotation = degree;
},
cbTouchStart(event) {
let pos = event.getLocation();
// 點選時顯示搖杆元件節點并設定位置
this.node.active = true;
let rPos = this.sceneNode.convertToNodeSpaceAR(pos); // 将世界坐标轉化為場景節點的相對坐标
this.node.setPosition(rPos);
// 初始化搖杆節點位置及角度
this.joystick.setPosition(cc.v2(0, 0));
this.dir = cc.v2(0, 0);
},
cbTouchMove(event) {
var pos = event.getLocation();
var jPos = this.node.convertToNodeSpaceAR(pos); // 将世界坐标轉化為搖杆元件節點的相對坐标
// 擷取搖杆的角度
let len = jPos.mag();
this.dir.x = jPos.x / len;
this.dir.y = jPos.y / len;
// 設定搖杆的位置
if (len > this.Max_r) {
jPos.x = this.Max_r * jPos.x / len;
jPos.y = this.Max_r * jPos.y / len;
}
this.joystick.setPosition(jPos);
},
cbTouchEnd(event) {
// 初始化搖杆節點位置及角度
this.joystick.setPosition(cc.v2(0, 0));
this.dir = cc.v2(0, 0);
this.node.active = false;
},
cbTouchCancel(event) {
// 初始化搖杆節點位置及角度
this.joystick.setPosition(cc.v2(0, 0));
this.dir = cc.v2(0, 0);
this.node.active = false;
}
});
4.最後将寫好的腳本挂載到 Rocker 節點上儲存為 Prefab 就可以使用了:
使用步驟:
1.建立好場景和玩家角色後,将 Rocker 元件拖到場景中,并将 Canvas 和 玩家角色挂載到對應的位置,設定好合适的移動速度和搖杆移動半徑後就可以使用了:
2.可以看到已經可以流暢的控制玩家移動了:
最後:
不知道小夥伴們學會了沒有,趕快來試試看吧,有什麼好的建議都可以在下面評論或者私信告訴我哦!
推薦閱讀:
讓蔡徐坤來教你實作遊戲中的幀動畫(上)
讓蔡徐坤來教你實作遊戲中的幀動畫(中)
一文教你實作「飛機大戰」裡戰機的控制邏輯
我是「Super于」,立志做一個每天都有正回報的人!