Cocos Creator制作一个虚拟摇杆
Cocos Creator制作一個虛擬搖桿
- 1. 演示
- 版本:v2.4.3
- 語言:TS
- 演示GIF
- 2. 實現過程
- 素材
- 期望效果
- 過程
- (1)搖桿跟隨觸摸
- (2)搖桿自動歸位
- (3)限制搖桿不出界
- 原理:
- (4)添加箭頭
- 原理:
- 主腳本編寫
- (1)主腳本部分實現功能
- (2)演示
- (3)實現
- 搖桿腳本部分
- 主腳本部分
- 第一次發文章,若有錯誤望大佬們指正。
- 源碼
1. 演示
版本:v2.4.3
語言:TS
演示GIF
2. 實現過程
素材
期望效果
- 類似于王者榮耀的那種小搖桿
- 搖桿中心位置為屏幕點擊的位置
- 搖桿點擊部分不會出界
過程
(1)搖桿跟隨觸摸
this.Joystick = this.node.getChildByName("Joystick");// 此處監聽的joystick為搖桿this.Joystick.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);onTouchMove(e: cc.Event.EventTouch) {this.JoystickMove(e)}JoystickMove(e: cc.Event.EventTouch) {// 移動let delta = e.getDelta();let moveDistance = cc.v3(delta.x / this.node.scale, delta.y / this.node.scale) // 此處增加縮放參數為了方便,使用時可以直接縮放大小this.Joystick.setPosition(this.Joystick.position.add(moveDistance)) }
此時可以實現觸摸點跟隨手指或者鼠標移動。getDelta函數是獲取觸點距離上一次事件移動的距離對象,返回的是一個Vec2。但此時搖桿不會自動歸位。
(2)搖桿自動歸位
this.Joystick.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);this.Joystick.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);onTouchEnd(e: cc.Event.EventTouch) {this.JoystickReset()}onTouchCancel(e: cc.Event.EventTouch) {this.JoystickReset()}JoystickReset() {cc.tween(this.Joystick).to(0.05, {x: 0, y: 0}).start()}TOUCH_END, TOUCH_CANCEL代表的狀態為當手指在目標節點區域內離開屏幕時,當手指在目標節點區域外離開屏幕時。使用緩動使動畫更流暢。
(3)限制搖桿不出界
原理:
此處思路來源于CSDN章魚仔,通過三角形的相似等比。
完善JoystickMove代碼
此時移動不會出界,而且可以任意調整縮放倍數都可以保持不出界狀態!
注意getLocation()函數返回的坐標是以屏幕左下角為坐標中心的坐標,并不是世界坐標!
節點.convertToNodeSpaceAR(位置)返回的是這個位置在這個節點下的位置。
(4)添加箭頭
完善代碼
再完善一下搖桿回彈時的動畫,讓箭頭可以復原!
JoystickReset() {let time: number = 0.05;let arrowReset = cc.tween(this.arrow).to(time, {width: 0, opacity: 0})cc.tween(this.Joystick).call(() => {arrowReset.start()}).to(time, {x: 0, y: 0}).start()}原理:
首先dir是搖桿的向量與搖桿中心的一個帶方向的向量差,若是求向量夾角必須有另外一個參考向量,此處定義為(0, 1),求出的值為弧度所以需要將弧度轉換為我們要的角度。
弧度轉角度公式: 角度 = 弧度 * 180 / PI
cocos中可以直接使用cc.misc.radiansToDegrees()
singAngle()函數源碼部分如下,如果對向量的叉乘、點乘的幾何意義不熟悉可以看一下:
/** 帶方向的夾角的弧度。該方法僅用做兼容 2D 計算。*/signAngle (vector) {cc.warnID(1408, 'vec3.signAngle', 'v2.1', 'cc.v2(selfVector).signAngle(vector)');let vec1 = new Vec2(this.x, this.y);let vec2 = new Vec2(vector.x, vector.y);return vec1.signAngle(vec2);}/** 帶方向的夾角的弧度。*/signAngle (vector: Vec2): number {let angle = this.angle(vector);return this.cross(vector) < 0 ? -angle : angle;}/** 夾角的弧度。*/angle (vector: Vec2): number {var magSqr1 = this.magSqr();var magSqr2 = vector.magSqr();if (magSqr1 === 0 || magSqr2 === 0) {console.warn("Can't get angle between zero vector");return 0.0;}var dot = this.dot(vector);var theta = dot / (Math.sqrt(magSqr1 * magSqr2));theta = misc.clampf(theta, -1.0, 1.0);return Math.acos(theta); // 反余弦函數}/** 當前向量與指定向量進行叉乘。*/cross (vector: Vec2): number {return this.x * vector.y - this.y * vector.x;}/***當前向量與指定向量進行點乘。*/dot (vector: Vec2): number {return this.x * vector.x + this.y * vector.y;}/** 限定浮點數的最大最小值。* 數值大于 max_inclusive 則返回 max_inclusive。* 數值小于 min_inclusive 則返回 min_inclusive。* 否則返回自身。*/misc.clampf = function (value, min_inclusive, max_inclusive) {if (min_inclusive > max_inclusive) {var temp = min_inclusive;min_inclusive = max_inclusive;max_inclusive = temp;}return value < min_inclusive ? min_inclusive : value < max_inclusive ? value : max_inclusive;};主腳本編寫
(1)主腳本部分實現功能
- 更改觸摸范圍為全屏
- 跨腳本調用搖桿
- 移動物體
(2)演示
(3)實現
搖桿腳本部分
// 返回給調用者需要用到的參數returnArrowAngle() {let radin = cc.misc.degreesToRadians(-this.arrow.angle - 90);cc.log(this.arrow.angle)let vec = cc.v2(0, 1);let targetVec = vec.rotate(-radin);let data = {angle: this.arrow.angle, // 角度vec: targetVec,speedScale: this.arrow.width / this.arrowMaxLenth,moveState: this.Joystick.x != 0 && this.Joystick.y != 0 ? true : false,}return data;}原理與計算朝向原理差不多,只是這次將角度轉為弧度,再通過將參考的向量旋轉指定弧度(radin)后,即可得出指定已知角度的向量!
主腳本部分
@property({type: cc.Node, displayName: "可點擊區域"})touchArea: cc.Node = null;@property({type: cc.Node, displayName: "搖桿"})joystick: cc.Node = null;@property({type: cc.Node, displayName: "移動物體"})thing: cc.Node = null;// 此腳本腳本全局函數區joystickCom: joystick;moveSpeed = 0.5;moveRotate: number;// 設置點擊區域監聽onLoad () {this.joystickCom = this.joystick.getComponent(joystick);this.touchArea.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);this.touchArea.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);this.touchArea.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);}onTouchStart(e: cc.Event.EventTouch) {this.joystickCom.onTouchStart(e);}onTouchMove(e: cc.Event.EventTouch) {this.joystickCom.onTouchMove(e);}onTouchEnd(e: cc.Event.EventTouch) {this.joystickCom.onTouchEnd(e);}// 移動實現thingMove() {let joystickFun = this.joystickCom.returnArrowAngle()this.thing.angle = joystickFun.angle + 90; // 自行調整if (joystickFun.moveState) {this.thing.setPosition(this.thing.position.add(cc.v3(joystickFun.vec.x * 5 * joystickFun.speedScale, joystickFun.vec.y * 5 * joystickFun.speedScale)))}}update (dt) {this.thingMove();} }第一次發文章,若有錯誤望大佬們指正。
源碼
密碼: agzg
總結
以上是生活随笔為你收集整理的Cocos Creator制作一个虚拟摇杆的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: UGUI 虚拟摇杆
- 下一篇: 修改群晖mac 及 sn