YaoGan.ts 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import AudioManager from "../AudioManager";
  2. import EventName from "../EventName/EventName";
  3. import { Global } from "../Global";
  4. import Character, { SpineAnimationState } from "./Character";
  5. const { ccclass, property } = cc._decorator;
  6. @ccclass
  7. export default class YaoGan extends cc.Component {
  8. @property(cc.Node)
  9. bg: cc.Node = null;//摇杆背景
  10. @property(cc.Node)
  11. joystick: cc.Node = null;//摇杆 也就是中心点
  12. @property(cc.Node)
  13. parent: cc.Node = null;//摇杆和背景的父节点
  14. max_R: number = 112//25;//摇杆移动的最大半径
  15. @property
  16. is_rotation: boolean = true;//角色是否根据摇杆的方向旋转
  17. @property
  18. is_forbidden: boolean = false;//是否禁用摇杆
  19. CurrentDir: cc.Vec2 = null
  20. CurrentPower: number = null
  21. //当前摇杆状态 false为摇杆取消 true为摇杆中
  22. CurrentYaoGanState: boolean = false
  23. //当前摇杆状态 false为摇杆取消 true为摇杆中
  24. CharacterComp: Character = null
  25. onLoad() {
  26. //绑定事件
  27. //因为摇杆很小,如果给摇杆绑定事件玩家将很难控制,摇杆的背景比较大,所以把事件都绑定在背景上是不错的选择
  28. this.node.on(cc.Node.EventType.TOUCH_MOVE, this.move, this);//当手指在背景上移动时触发move事件
  29. this.node.on(cc.Node.EventType.TOUCH_END, this.finish, this);//当手指在目标节点区域内离开屏幕时触发finish事件
  30. this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.finish, this);//当手指在目标节点区域外离开屏幕时触发finish事件
  31. }
  32. protected start(): void {
  33. cc.Camera.main.node.on(cc.Node.EventType.TOUCH_START, this.CameraMove, this);//当手指在背景上移动时触发move事件
  34. cc.Camera.main.node.on(cc.Node.EventType.TOUCH_END, this.resetYaogan, this);//当手指在背景上移动时触发move事件
  35. }
  36. posss: cc.Vec2
  37. CameraMove(event: cc.Event.EventTouch) {
  38. const pos = event.getLocation()
  39. let pp = cc.Camera.main.getScreenToWorldPoint(pos)
  40. let pp1 = this.node.parent.convertToNodeSpaceAR(pp)
  41. this.node.setPosition(pp1)
  42. this.node.opacity = 255
  43. }
  44. move(event: cc.Event.EventTouch) {//负责移动摇杆 手指移动时调用
  45. if (this.is_forbidden == false) {//如果没有禁用摇杆
  46. // event.stopPropagation()
  47. let Camera = cc.Camera.main.node.position
  48. let pos = cc.v2(event.getLocationX() + Camera.x, event.getLocationY() + Camera.y);//获取触点的坐标
  49. let pos_0 = this.parent.convertToNodeSpaceAR(pos);//将一个点转换到节点 (局部) 空间坐标系,这个坐标系以锚点为原点。
  50. pos_0.x = pos_0.x / Global.YaoGanSpeedX
  51. pos_0.y = pos_0.y / Global.YaoGanSpeedY
  52. if (pos_0.mag() < this.max_R) {//如果触点长度小于我们规定好的最大半径
  53. this.joystick.x = pos_0.x;//摇杆的坐标为触点坐标
  54. this.joystick.y = pos_0.y;
  55. } else {//如果不
  56. let pos = pos_0.normalizeSelf();//将触点归一化
  57. // console.log('pos', pos.x, pos.y)
  58. let x = pos.x * this.max_R;//归一化的触点坐标 × 最大半径
  59. let y = pos.y * this.max_R;
  60. this.joystick.x = x;//给摇杆坐标赋值
  61. this.joystick.y = y;
  62. }
  63. let SendMove = () => {
  64. this.bg.color = cc.Color.WHITE
  65. this.CurrentYaoGanState = true
  66. //方向取反
  67. this.CurrentDir = pos_0.normalizeSelf()
  68. this.CurrentDir.x = -this.CurrentDir.x
  69. this.CurrentDir.y = -this.CurrentDir.y
  70. this.CurrentPower = (cc.v2(this.joystick.x, this.joystick.y).mag() / this.max_R)
  71. cc.systemEvent.emit(EventName.YaoGanMove, this.CurrentDir, this.CurrentPower);
  72. cc.systemEvent.emit(EventName.ChangeRoleState, SpineAnimationState.Xuli);
  73. }
  74. if (this?.CharacterComp?.Fly) {
  75. SendMove()
  76. } else {
  77. if (pos_0.y > 0) {
  78. this.bg.color = cc.Color.RED
  79. cc.systemEvent.emit(EventName.YaoGanCancel);
  80. this.CurrentYaoGanState = false
  81. cc.systemEvent.emit(EventName.ChangeRoleState, SpineAnimationState.Idle);
  82. } else {
  83. if (this.PlayEffectOnce) {
  84. this.PlayEffectOnce = false
  85. AudioManager.instance.playEffect(AudioManager.预发射音效)
  86. }
  87. SendMove()
  88. }
  89. }
  90. }
  91. }
  92. PlayEffectOnce: boolean = true
  93. finish() {//摇杆弹回原位置
  94. if (this.CurrentYaoGanState) {
  95. cc.systemEvent.emit(EventName.YaoGanEnd, this.CurrentDir, this.CurrentPower);
  96. cc.systemEvent.emit(EventName.ChangeRoleState, SpineAnimationState.Fly);
  97. }
  98. this.resetYaogan()
  99. }
  100. resetYaogan() {
  101. //恢复蓄力音效
  102. this.PlayEffectOnce = true
  103. //摇杆坐标和移动向量都为(0,0)
  104. this.joystick.position = cc.v3(0, 0);
  105. this.node.opacity = 0
  106. }
  107. }
  108. //////////////////////////////