import AudioManager from "../AudioManager"; import EventName from "../EventName/EventName"; import { Global } from "../Global"; import Character, { SpineAnimationState } from "./Character"; 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 = 112//25;//摇杆移动的最大半径 @property is_rotation: boolean = true;//角色是否根据摇杆的方向旋转 @property is_forbidden: boolean = false;//是否禁用摇杆 CurrentDir: cc.Vec2 = null CurrentPower: number = null //当前摇杆状态 false为摇杆取消 true为摇杆中 CurrentYaoGanState: boolean = false //当前摇杆状态 false为摇杆取消 true为摇杆中 CharacterComp: Character = null onLoad() { //绑定事件 //因为摇杆很小,如果给摇杆绑定事件玩家将很难控制,摇杆的背景比较大,所以把事件都绑定在背景上是不错的选择 this.node.on(cc.Node.EventType.TOUCH_MOVE, this.move, this);//当手指在背景上移动时触发move事件 this.node.on(cc.Node.EventType.TOUCH_END, this.finish, this);//当手指在目标节点区域内离开屏幕时触发finish事件 this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.finish, this);//当手指在目标节点区域外离开屏幕时触发finish事件 } protected start(): void { cc.Camera.main.node.on(cc.Node.EventType.TOUCH_START, this.CameraMove, this);//当手指在背景上移动时触发move事件 cc.Camera.main.node.on(cc.Node.EventType.TOUCH_END, this.resetYaogan, this);//当手指在背景上移动时触发move事件 } posss: cc.Vec2 CameraMove(event: cc.Event.EventTouch) { const pos = event.getLocation() let pp = cc.Camera.main.getScreenToWorldPoint(pos) let pp1 = this.node.parent.convertToNodeSpaceAR(pp) this.node.setPosition(pp1) this.node.opacity = 255 } move(event: cc.Event.EventTouch) {//负责移动摇杆 手指移动时调用 if (this.is_forbidden == false) {//如果没有禁用摇杆 // event.stopPropagation() 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);//将一个点转换到节点 (局部) 空间坐标系,这个坐标系以锚点为原点。 pos_0.x = pos_0.x / Global.YaoGanSpeedX pos_0.y = pos_0.y / Global.YaoGanSpeedY 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; } let SendMove = () => { this.bg.color = cc.Color.WHITE this.CurrentYaoGanState = true //方向取反 this.CurrentDir = pos_0.normalizeSelf() this.CurrentDir.x = -this.CurrentDir.x this.CurrentDir.y = -this.CurrentDir.y this.CurrentPower = (cc.v2(this.joystick.x, this.joystick.y).mag() / this.max_R) cc.systemEvent.emit(EventName.YaoGanMove, this.CurrentDir, this.CurrentPower); cc.systemEvent.emit(EventName.ChangeRoleState, SpineAnimationState.Xuli); } if (this?.CharacterComp?.Fly) { SendMove() } else { if (pos_0.y > 0) { this.bg.color = cc.Color.RED cc.systemEvent.emit(EventName.YaoGanCancel); this.CurrentYaoGanState = false cc.systemEvent.emit(EventName.ChangeRoleState, SpineAnimationState.Idle); } else { if (this.PlayEffectOnce) { this.PlayEffectOnce = false AudioManager.instance.playEffect(AudioManager.预发射音效) } SendMove() } } } } PlayEffectOnce: boolean = true finish() {//摇杆弹回原位置 if (this.CurrentYaoGanState) { cc.systemEvent.emit(EventName.YaoGanEnd, this.CurrentDir, this.CurrentPower); cc.systemEvent.emit(EventName.ChangeRoleState, SpineAnimationState.Fly); } this.resetYaogan() } resetYaogan() { //恢复蓄力音效 this.PlayEffectOnce = true //摇杆坐标和移动向量都为(0,0) this.joystick.position = cc.v3(0, 0); this.node.opacity = 0 } } //////////////////////////////