LevelAction.ts 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. import { _decorator, BoxCollider2D, Button, CircleCollider2D, Collider2D, Component, find, instantiate, Node, NodeEventType, tween, view, Vec3, mat4, UITransform } from 'cc';
  2. import { resLoader, ResLoader } from '../../core_tgx/base/ResLoader';
  3. import { CupHeight, TakeGobletGlobalInstance, WaterColors } from './TakeGobletGlobalInstance';
  4. import { OutArea } from './Component/OutArea';
  5. import { WaitArea } from './Component/WaitArea';
  6. import { CocktailCup } from './Component/CocktailCup';
  7. import { OriginCup } from './Component/OriginCup';
  8. import { Water } from './Component/Water';
  9. import { EventDispatcher } from '../../core_tgx/easy_ui_framework/EventDispatcher';
  10. import { GameEvent } from './Enum/GameEvent';
  11. const { ccclass, property } = _decorator;
  12. @ccclass('LevelAction')
  13. export class LevelAction extends Component {
  14. @property(OutArea)
  15. outArea: OutArea = null!; // 直接引用OutArea组件
  16. @property(WaitArea)
  17. waitArea: WaitArea = null!; // 直接引用WaitArea组件
  18. @property(Node)
  19. tempCups: Node = null!; //临时杯
  20. @property(Node)
  21. goblets: Node = null!; //原浆区
  22. start() {
  23. this.registerListener();
  24. this.generateInitialCups(); // 自动初始化
  25. }
  26. onDestroy() {
  27. this.unregisterListener();
  28. }
  29. registerListener() {
  30. EventDispatcher.instance.on(GameEvent.EVENT_CLICK_ORIGIN_CUP, this.handlePourOriginCup, this);
  31. }
  32. unregisterListener() {
  33. EventDispatcher.instance.off(GameEvent.EVENT_CLICK_ORIGIN_CUP, this.handlePourOriginCup, this);
  34. }
  35. private async generateInitialCups() {
  36. const instance = TakeGobletGlobalInstance.instance;
  37. const configs = instance.getInitialCupsConfig();
  38. const allCups: Node[] = [];
  39. for (const config of configs) {
  40. for (let i = 0; i < config.count; i++) {
  41. const prefab = await instance.loadAsyncCocktail(config.height);
  42. const cupNode = instantiate(prefab);
  43. const cup = cupNode.getComponent(CocktailCup)!;
  44. // 设置颜色并重置水位
  45. cup.cupColor = instance.getRandomColor();
  46. cup.reset();
  47. allCups.push(cupNode);
  48. }
  49. }
  50. console.log('allCups: ', allCups.length);
  51. // 分配初始位置
  52. allCups.slice(0, 2).forEach(cup => this.outArea.addCup(cup));
  53. allCups.slice(2).forEach(cup => this.waitArea.addCup(cup));
  54. // 在分配完调酒杯后添加
  55. this.generateOriginCups();
  56. }
  57. // 当调酒区杯子被消除时调用
  58. public async handleCupsRemoved(count: number) {
  59. for (let i = 0; i < count; i++) {
  60. const cup = this.waitArea.takeCup();
  61. if (cup) {
  62. this.outArea.addCup(cup);
  63. }
  64. }
  65. }
  66. private generateOriginCups() {
  67. const outCups = this.outArea.getCups() as Node[];
  68. const waitCups = this.waitArea.getCups() as Node[];
  69. const allCups = [...outCups, ...waitCups].slice(0, 7);
  70. const colors = allCups.map(cup => {
  71. const comp = cup.getComponent(CocktailCup);
  72. return comp ? comp.cupColor : WaterColors.Blue;
  73. });
  74. this.goblets.children.forEach(originCupNode => {
  75. const originCup = originCupNode.getComponent(OriginCup)!;
  76. const waters = originCup.waters.children;
  77. for (let i = 0; i < originCup.cupHeight; i++) {
  78. const waterNode = waters[i];
  79. const water = waterNode.getComponent(Water);
  80. if (water) {
  81. water.initColor(colors[Math.floor(Math.random() * colors.length)]);
  82. waterNode.active = true;
  83. }
  84. }
  85. });
  86. }
  87. public async handlePourOriginCup(originCup: OriginCup) {
  88. // 如果子节点0是底层,需要反转顺序
  89. const colors: WaterColors[] = [];
  90. for (let i = originCup.waters.children.length - 1; i >= 0; i--) {
  91. const waterNode = originCup.waters.children[i];
  92. if (waterNode.active) {
  93. const water = waterNode.getComponent(Water)!;
  94. colors.push(water.color);
  95. }
  96. }
  97. // 处理每个颜色层(从顶层开始)
  98. for (const color of colors) {
  99. const targetCup = this.findTargetCupInOutArea(color);
  100. if (!targetCup) {
  101. console.log(`未找到颜色为${WaterColors[color]}的调酒杯,停止倒水`);
  102. return;
  103. }
  104. await this.pourAnimation(originCup.node, targetCup.node, color);
  105. // 隐藏当前处理的水层(顶层)
  106. const activeWaters = originCup.waters.children.filter(n => n.active);
  107. if (activeWaters.length > 0) {
  108. const topIndex = activeWaters.length - 1;
  109. activeWaters[topIndex].active = false;
  110. }
  111. }
  112. }
  113. private findTargetCupInOutArea(color: WaterColors): CocktailCup | null {
  114. // 严格过滤调酒区杯子
  115. const validCups = this.outArea.getCups()
  116. .map(node => node.getComponent(CocktailCup))
  117. .filter(cup =>
  118. cup !== null &&
  119. cup.cupColor === color &&
  120. !cup.isFull()
  121. ) as CocktailCup[];
  122. // 优先选择剩余容量最小的杯子(后进先满)
  123. return validCups.sort((a, b) => a.remainingCapacity - b.remainingCapacity)[0] || null;
  124. }
  125. private async pourAnimation(origin: Node, target: Node, color: WaterColors) {
  126. // 使用UITransform转换坐标
  127. const targetWorldPos = target.worldPosition;
  128. const originParent = origin.parent!;
  129. const localPos = originParent.getComponent(UITransform)!.convertToNodeSpaceAR(targetWorldPos);
  130. localPos.y += 150; // Y轴偏移
  131. await new Promise<void>(resolve => {
  132. tween(origin)
  133. .to(0.3, { position: localPos })
  134. .call(() => resolve())
  135. .start();
  136. });
  137. // 添加水层并设置颜色
  138. const cocktailCup = target.getComponent(CocktailCup);
  139. if (cocktailCup && !cocktailCup.isFull()) {
  140. cocktailCup.addLayer(color);
  141. }
  142. }
  143. }