原始碼獲取方式在最下面
先看效果

本文分為兩個部分
如何使用
原理講解
如何使用
一共需要四個節點
- 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~~
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/176147.html
標籤:其他
上一篇:pyhton實作猜單詞游戲
