import EventName from "../EventName/EventName"; const { ccclass, property } = cc._decorator; @ccclass export default class YaoGan extends cc.Component { @property(cc.Node) bg: cc.Node = null;//摇杆背景 @property(cc.Node) joystick: cc.Node = null;//摇杆 也就是中心点 @property(cc.Node) parent: cc.Node = null;//摇杆和背景的父节点 max_R: number = 70//25;//摇杆移动的最大半径 @property is_rotation: boolean = true;//角色是否根据摇杆的方向旋转 @property is_forbidden: boolean = false;//是否禁用摇杆 CurrentDir: cc.Vec2 = null CurrentPower: number = null onLoad() { //绑定事件 //因为摇杆很小,如果给摇杆绑定事件玩家将很难控制,摇杆的背景比较大,所以把事件都绑定在背景上是不错的选择 this.bg.on(cc.Node.EventType.TOUCH_MOVE, this.move, this);//当手指在背景上移动时触发move事件 this.bg.on(cc.Node.EventType.TOUCH_END, this.finish, this);//当手指在目标节点区域内离开屏幕时触发finish事件 this.bg.on(cc.Node.EventType.TOUCH_CANCEL, this.finish, this);//当手指在目标节点区域外离开屏幕时触发finish事件 } move(event: cc.Event.EventTouch) {//负责移动摇杆 手指移动时调用 if (this.is_forbidden == false) {//如果没有禁用摇杆 let Camera = cc.Camera.main.node.position let pos = cc.v2(event.getLocationX() + Camera.x, event.getLocationY()+ Camera.y);//获取触点的坐标 let pos_0 = this.parent.convertToNodeSpaceAR(pos);//将一个点转换到节点 (局部) 空间坐标系,这个坐标系以锚点为原点。 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();//将触点归一化 // console.log('pos', pos.x, pos.y) let x = pos.x * this.max_R;//归一化的触点坐标 × 最大半径 let y = pos.y * this.max_R; this.joystick.x = x;//给摇杆坐标赋值 this.joystick.y = y; } this.CurrentDir = pos_0.normalizeSelf() this.CurrentPower = (cc.v2(this.joystick.x, this.joystick.y).mag() / this.max_R) cc.systemEvent.emit(EventName.YaoGanMove, this.CurrentDir, this.CurrentPower); } } finish() {//摇杆弹回原位置 cc.systemEvent.emit(EventName.YaoGanEnd, this.CurrentDir, this.CurrentPower); //摇杆坐标和移动向量都为(0,0) this.joystick.position = cc.v3(0, 0); } }