Guide.ts 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. import GuideVO from "./GuideVO";
  2. /**
  3. * @description 新手引导
  4. * @author 邹勇
  5. */
  6. const { ccclass, property } = cc._decorator;
  7. @ccclass
  8. export default class Guide extends cc.Component {
  9. @property({ type: cc.Node, displayName: "显示区域" })
  10. node_display: cc.Node = null;
  11. @property({ type: cc.Node, displayName: "点击区域" })
  12. node_click: cc.Node = null;
  13. @property({ type: cc.Node, displayName: "背景" })
  14. node_bg: cc.Node = null;
  15. @property({ type: cc.Node, displayName: "对话框" })
  16. node_dialog: cc.Node = null;
  17. @property({ type: cc.Node, displayName: "手指" })
  18. node_finger: cc.Node = null;
  19. @property({ type: cc.Sprite, displayName: "头像" })
  20. node_head: cc.Sprite = null;
  21. @property({ type: sp.Skeleton, displayName: "形象" })
  22. node_person: sp.Skeleton = null;
  23. @property({ type: cc.RichText, displayName: "对话内容" })
  24. rich_dialog: cc.RichText = null;
  25. private guides: GuideVO[];
  26. private crtStep: number;
  27. private crtGuide: GuideVO;
  28. private targetNode: cc.Node;
  29. private event_data: string;
  30. /** 对话框对齐方式 上下左右中 */
  31. private widgets: string[] = ['top', 'bottom', 'left', 'right', 'verticalCenter', 'horizontalCenter'];
  32. onLoad() {
  33. }
  34. start() {
  35. if (gData.guideData.crtID == null) {
  36. this.node.destroy();
  37. return;
  38. }
  39. this.guides = gData.guideData.getGuidesByID(gData.guideData.crtID);
  40. this.crtStep = -1;
  41. this.nextStep();
  42. }
  43. private nextStep() {
  44. this.crtStep++;
  45. this.crtGuide = this.guides[this.crtStep];
  46. this.updateGuide();
  47. }
  48. private updateGuide() {
  49. if (this.crtGuide == null) {
  50. this.close();
  51. }
  52. else {
  53. this.node_bg.opacity = 180;
  54. this.node_finger.opacity = 255;
  55. this.node_dialog.opacity = 255;
  56. this.targetNode = null;
  57. this.event_data = null;
  58. let [x, y, w, h] = [null, null, null, null];
  59. //点击全屏下一步,显示区域不显示,点击区域全屏
  60. if (this.crtGuide.click_rect == "all") {
  61. this.node_display.width = this.node_display.height = 0;
  62. this.node_click.x = 0;
  63. this.node_click.y = 0;
  64. this.node_click.width = this.node.width;
  65. this.node_click.height = this.node.height;
  66. }
  67. else if (this.crtGuide.click_rect.indexOf("event") != -1) {//点击区域下一步,并发送事件,显示区域读配置,点击区域=显示区域
  68. this.event_data = this.crtGuide.id + "_" + this.crtStep;
  69. let arr = this.crtGuide.display_rect.split(":");
  70. x = parseInt(arr[0]);
  71. y = parseInt(arr[1]);
  72. w = parseInt(arr[2]);
  73. h = parseInt(arr[3]);
  74. this.node_click.x = x;
  75. this.node_click.y = y;
  76. this.node_click.width = w;
  77. this.node_click.height = h;
  78. }
  79. else {//点击按钮下一步,显示区域为配置的node,点击区域=显示区域
  80. this.targetNode = cc.find("Canvas/" + this.crtGuide.click_rect);
  81. w = this.targetNode.width;
  82. h = this.targetNode.height;
  83. let pos = mk.game.getWorldPos(this.targetNode);
  84. x = pos.x;
  85. y = pos.y;
  86. //穿透点击目标节点时增加一个事件触发下一步,触发后移除
  87. this.node_click.width = this.node_click.height = 0;
  88. let eventHandler = new cc.Component.EventHandler();
  89. eventHandler.target = this.node;
  90. eventHandler.component = "Guide";
  91. eventHandler.handler = "clickNodeClick";
  92. this.targetNode.getComponent(cc.Button).clickEvents.push(eventHandler);
  93. }
  94. //显示区域由大到小动画
  95. if (x != null && y != null && w != null && h != null) {
  96. //先重置
  97. this.node_bg.x = this.node_bg.y = this.node_display.x = this.node_display.y = 0;
  98. this.node_display.width = this.node.width;
  99. this.node_display.height = this.node.height;
  100. //动画
  101. cc.tween(this.node_display)
  102. .to(0.3, { x: x, y: y, width: w, height: h }, {
  103. onUpdate: () => {
  104. this.node_bg.x = -this.node_display.x;
  105. this.node_bg.y = -this.node_display.y;
  106. }
  107. })
  108. .start();
  109. }
  110. //对话框位置
  111. ////全屏对齐
  112. if (this.crtGuide.dialog_pos != null && this.crtGuide.dialog_pos.length > 0) {
  113. let arr = this.crtGuide.dialog_pos.split(":");
  114. let wedgit = this.node_dialog.getComponent(cc.Widget);
  115. for (let i = 0; i < this.widgets.length; i++) {
  116. wedgit[this.widgets[i]] = arr[i] == "" ? null : parseInt(arr[i]);
  117. }
  118. }
  119. else {//显示区域偏移
  120. let arr = this.crtGuide.dialog_pos1.split(",");
  121. this.node_dialog.x = x + parseInt(arr[0]);
  122. this.node_dialog.y = y + parseInt(arr[1]);
  123. }
  124. //对话文字对齐方式
  125. let a = this.crtGuide.dialog_alignment;
  126. this.rich_dialog.horizontalAlign = a == '0' ? cc.macro.TextAlignment.LEFT : (a == '1' ? cc.macro.TextAlignment.CENTER : cc.macro.TextAlignment.RIGHT);
  127. if (this.crtGuide.finger == "") {
  128. this.node_finger.active = false;
  129. }
  130. else {
  131. this.node_finger.active = true;
  132. let arr = this.crtGuide.finger.split(":");
  133. this.node_finger.x = x + parseInt(arr[0]);
  134. this.node_finger.y = y + parseInt(arr[1]);
  135. }
  136. if (this.crtGuide.tr_form == 1) {
  137. this.node_head.node.active = true;
  138. this.node_person.node.active = false;
  139. }
  140. else {
  141. this.node_head.node.active = false;
  142. this.node_person.node.active = true;
  143. }
  144. this.rich_dialog.string = this.crtGuide.dialog;
  145. }
  146. }
  147. async clickNodeClick() {
  148. mk.audio.playEffect("button");
  149. cc.Tween.stopAllByTarget(this.node_display);
  150. console.log("clickNodeClick");
  151. if (this.targetNode) {
  152. this.targetNode.getComponent(cc.Button).clickEvents.pop();
  153. }
  154. if (this.event_data) {
  155. //event_guide data:1_2 (1_2为新手引导的id)
  156. mk.event.emit("event_guide", this.event_data);
  157. }
  158. this.reset();
  159. if (this.crtGuide.lag_next > 0) {
  160. await mk.time.WaitForSeconds(this.crtGuide.lag_next);
  161. }
  162. this.nextStep();
  163. }
  164. /** 等待状态 透明不可点击 */
  165. private reset() {
  166. this.node_display.width = 0;
  167. this.node_display.height = 0;
  168. this.node_bg.x = -this.node_display.x;
  169. this.node_bg.y = -this.node_display.y;
  170. this.node_bg.opacity = 0;
  171. this.node_click.width = 0
  172. this.node_click.height = 0;
  173. this.node_finger.opacity = 0;
  174. this.node_dialog.opacity = 0;
  175. }
  176. private close() {
  177. mk.guide.close();
  178. this.node.destroy();
  179. }
  180. }