CocktailCup.ts 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. import { _decorator, Color, Component, Enum, Node, Sprite, tween, Vec3, UITransform, view, sp, Game, UIOpacity } from 'cc';
  2. import { CupHeight, WaterColorHex, WaterColors } from '../TakeGobletGlobalInstance';
  3. import { Water } from './Water';
  4. import { EventDispatcher } from 'db://assets/core_tgx/easy_ui_framework/EventDispatcher';
  5. import { GameEvent } from '../Enum/GameEvent';
  6. import { OutArea } from './OutArea';
  7. import { GameUtil } from '../GameUtil';
  8. import { TakeGobletAudioMgr } from '../Manager/TakeGobletAudioMgr';
  9. const { ccclass, property, executeInEditMode } = _decorator;
  10. //调酒杯状态 默认 接水
  11. export enum CocktailCupState {
  12. Default,
  13. GetWater,
  14. Move,
  15. Full
  16. }
  17. /** 调酒杯组件脚本*/
  18. @ccclass('CocktailCup')
  19. // @executeInEditMode
  20. export class CocktailCup extends Component {
  21. @property(Node)
  22. waters: Node = null! //水流节点
  23. @property(sp.Skeleton)
  24. colorB: sp.Skeleton = null! //水流颜色骨骼
  25. @property(Node)
  26. good: Node = null!;
  27. @property({ type: Enum(CupHeight), displayName: '杯高度' })
  28. cupHeight: CupHeight = CupHeight.Two
  29. @property({ type: Enum(WaterColors) })
  30. private _cupColor: WaterColors = WaterColors.Blue
  31. @property({ type: Enum(WaterColors) })
  32. get cupColor() {
  33. return this._cupColor
  34. }
  35. set cupColor(value) {
  36. this._cupColor = value
  37. this.changeColor()
  38. }
  39. currentLayers: number = 0;
  40. onLoad() {
  41. this.playAnimationByState(CocktailCupState.Default);
  42. }
  43. changeColor() {
  44. const color = new Color(WaterColorHex[this.cupColor]);
  45. this.waters.children.forEach((water, index) => {
  46. water.getComponent(sp.Skeleton)!.color = color;
  47. })
  48. this.colorB.color = color;
  49. }
  50. /** 添加图层 接水动画*/
  51. async addLayer() {
  52. this.currentLayers++;
  53. this.playAnimationByState(CocktailCupState.GetWater);
  54. await GameUtil.delay(0.4);
  55. await this.checkAndDestroy();
  56. }
  57. //补满水
  58. public async fillUp() {
  59. if (!this.node) return;
  60. TakeGobletAudioMgr.playOneShot(TakeGobletAudioMgr.getMusicIdName(5), 1.0);
  61. this.playAnimationByState(CocktailCupState.Full);
  62. this.fadeOut();
  63. await GameUtil.delay(0.5);
  64. // 补满后执行移动销毁动画
  65. const uiTransform = this.node.getComponent(UITransform)!;
  66. const screenWidth = view.getVisibleSize().width;
  67. const targetX = screenWidth + uiTransform.width * 1.5;
  68. await new Promise<void>(resolve => {
  69. tween(this.node)
  70. .to(0.5, { position: new Vec3(targetX, 0, 0) }, { easing: 'sineIn' })
  71. .call(async () => {
  72. const outArea = this.node.parent?.parent?.getComponent(OutArea);
  73. if (outArea) {
  74. this.node.removeFromParent(); // 先从父节点移除
  75. this.node.destroy();
  76. await outArea.arrangeCups(); // 等待排列完成
  77. }
  78. resolve();
  79. })
  80. .start();
  81. });
  82. }
  83. //渐隐效果
  84. fadeOut() {
  85. if (!this.good) return;
  86. const uiOpacity = this.good.getComponent(UIOpacity)!;
  87. this.good.active = true;
  88. uiOpacity.opacity = 255;
  89. tween(uiOpacity)
  90. .to(0.5, { opacity: 0 }, { easing: 'sineIn' })
  91. .call(() => {
  92. this.good.active = false;
  93. })
  94. .start();
  95. }
  96. //播放动画
  97. playAnimationByState(state: CocktailCupState) {
  98. const waters = this.waters.children;
  99. const siblingNodes = this.node.children.filter(child => child.name !== 'waters' && child.name !== 'good');
  100. const allNodes = [...waters, ...siblingNodes];
  101. switch (state) {
  102. case CocktailCupState.GetWater:
  103. this.setSpineTimeScale(1.5);
  104. allNodes.forEach(child => child.getComponent(sp.Skeleton)!.setAnimation(0, `pour_0${this.currentLayers}`, false));
  105. break;
  106. case CocktailCupState.Move:
  107. allNodes.forEach(child => child.getComponent(sp.Skeleton)!.setAnimation(0, 'move', false));
  108. break;
  109. case CocktailCupState.Full:
  110. allNodes.forEach(child => child.getComponent(sp.Skeleton)!.setAnimation(0, 'full', false));
  111. break;
  112. default:
  113. allNodes.forEach(child => child.getComponent(sp.Skeleton)!.setAnimation(0, 'idle', false));
  114. break;
  115. }
  116. }
  117. //设置spine 时间缩放率
  118. setSpineTimeScale(timeScale: number = 1) {
  119. if (!this.node) return;
  120. const spineComponents = this.node.getComponentsInChildren(sp.Skeleton);
  121. spineComponents.forEach(spine => {
  122. spine.timeScale = timeScale;
  123. });
  124. }
  125. protected onDestroy(): void {
  126. EventDispatcher.instance.emit(GameEvent.EVENT_REFRESH_REMAIN_CUP);
  127. }
  128. // 清空水层(消除时调用)
  129. reset() {
  130. this.currentLayers = 0;
  131. }
  132. get isFull(): boolean {
  133. return this.currentLayers >= this.cupHeight;
  134. }
  135. private async checkAndDestroy() {
  136. if (this.isFull) {
  137. await this.fillUp();
  138. }
  139. }
  140. public get currentColor(): WaterColors {
  141. return this.cupColor;
  142. }
  143. public get remainingCapacity(): number {
  144. return this.cupHeight - this.currentLayers;
  145. }
  146. }