摘要
关于摇杆的实现网上有很多,但是耦合度比较高。今天 KUOKUO 将摇杆实现抽出来,单独一个脚本并声明了一个可拖入回调。
正文
版本说明
使用 CocosCreator 的 2.2.0 版本演示。

节点层级
新建个空节点作为管理节点(joystick),然后是背景与中心节点。

监听事件建议把监听写在背景节点,这样触摸范围大些,体验好。
start () { this.joyBk.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this); this.joyBk.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this); this.joyBk.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this); this.joyBk.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this); },
|
最大限制
获取到触摸位置后转化节点坐标下位置。
let pos = this.node.convertToNodeSpaceAR(e.getLocation());
|
然后,如果手指出圆了,要进行限位。假如最大半径 100,触摸位置为 150,那么就让 150 乘以 100/150;这样就转化回来了。
clampPos (pos) { let len = pos.mag(); if (len > this.maxR) { let k = this.maxR / len; pos.x *= k; pos.y *= k; } },
|
完整的处理代码:
let pos = this.node.convertToNodeSpaceAR(e.getLocation()); this.clampPos(pos); this.midNode.setPosition(pos.x, pos.y);
|
回调数据
这样我们就算出了位置,接下来算角度。
covertToAngle (pos) { let r = Math.atan2(pos.y, pos.x); let d = cc.misc.radiansToDegrees(r); return d; },
|
好了,位置和角度都有了,摇杆的脚本任务完成了,那么如何做个回调呢?先声明一个变量,类型为 cc.Component.EventHandler。
properties: { joyCallBack: { default: [], type: cc.Component.EventHandler, displayName: '摇杆移动回调', tooltip: '触发touchmove后分发数据' } },
|
然后将数据传出去:
onTouchMove (e) { let pos = this.node.convertToNodeSpaceAR(e.getLocation()); this.clampPos(pos); this.midNode.setPosition(pos.x, pos.y); let angle = this.covertToAngle(pos); this.joyCallBack[0].emit([pos, angle]); },
|

玩家脚本:
cc.Class({ extends: cc.Component,
properties: { },
onLoad () { this.vector = cc.v2(0, 0); },
playerMoving (vector, angle) { this.vector.x = vector.x; this.vector.y = vector.y; if (angle) { this.node.angle = angle; } },
update (dt) { const speed = 0.02; this.node.x += this.vector.x * speed; this.node.y += this.vector.y * speed; }, });
|
结语
这样就实现了摇杆脚本只处理摇杆数据,谁用谁传个回调进来。
2019!让我们一起学习!
O(∩_∩)O~~
源码在我的 GitHub 的 MyComponent 中
https://github.com/KuoKuo666;