OutArea.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import { _decorator, Component, Node, tween, Vec3, view } from 'cc';
  2. import { EventDispatcher } from 'db://assets/core_tgx/easy_ui_framework/EventDispatcher';
  3. import { GameEvent } from '../Enum/GameEvent';
  4. import { CocktailCup } from '../Component/CocktailCup';
  5. const { ccclass, property, executeInEditMode } = _decorator;
  6. @ccclass('OutArea')
  7. @executeInEditMode
  8. export class OutArea extends Component {
  9. @property(Node)
  10. outNodes: Node = null!;
  11. // 直接使用outNodes的子节点管理
  12. get cups() {
  13. return this.outNodes.children;
  14. }
  15. start() {
  16. this.registerEvent();
  17. // console.log('视图的设计分辨率:', view.getDesignResolutionSize());
  18. // console.log('视图窗口可见区域尺寸:', view.getVisibleSize());
  19. // 获取设计分辨率和实际窗口尺寸
  20. const designSize = view.getDesignResolutionSize();
  21. const visibleSize = view.getVisibleSize();
  22. // 计算高度的缩放比例
  23. const scaleY = visibleSize.height / designSize.height;
  24. const originalY = this.node.worldPosition.y;
  25. const designSizeY = designSize.height * (scaleY - 1);
  26. const visibleSizeY = visibleSize.height * (scaleY - 1);
  27. this.node.worldPosition = new Vec3(this.node.worldPosition.x, originalY + (visibleSizeY - designSizeY), 0);
  28. }
  29. protected onDestroy(): void {
  30. EventDispatcher.instance.off(GameEvent.EVENT_FILL_UP, this.onFillUp, this);
  31. }
  32. private registerEvent(): void {
  33. EventDispatcher.instance.on(GameEvent.EVENT_FILL_UP, this.onFillUp, this);
  34. }
  35. private async onFillUp(): Promise<void> {
  36. console.log('补满');
  37. // 获取所有有效杯子
  38. const validCups = this.cups.filter(cup => cup.isValid);
  39. if (validCups.length === 0) return;
  40. // 找到最右边的杯子(x坐标最大的)
  41. const rightMostCup = validCups.reduce((prev, current) => {
  42. return prev.position.x > current.position.x ? prev : current;
  43. });
  44. const cocktailCup = rightMostCup.getComponent(CocktailCup);
  45. if (cocktailCup) {
  46. try {
  47. // 执行补满动画并等待完成
  48. await cocktailCup.fillUp();
  49. EventDispatcher.instance.emit(GameEvent.EVENT_RIGHT_CUP_FULL);
  50. } catch (e) {
  51. console.error('补满操作失败:', e);
  52. }
  53. }
  54. }
  55. update(deltaTime: number) {
  56. }
  57. // 排列方法为异步
  58. async arrangeCups() {
  59. const startX = 50;
  60. const spacing = 100;
  61. // 过滤掉已销毁的节点
  62. const validCups = this.cups.filter(cup => cup.isValid);
  63. await new Promise<void>(resolve => {
  64. let completed = 0;
  65. validCups.forEach((cup, index) => {
  66. const targetX = startX + index * spacing;
  67. tween(cup)
  68. .to(0.3, { position: new Vec3(targetX, 0, 0) }, { easing: 'sineOut' })
  69. .call(() => {
  70. if (++completed === validCups.length) resolve();
  71. })
  72. .start();
  73. });
  74. // 处理无动画的情况
  75. if (validCups.length === 0) resolve();
  76. });
  77. }
  78. addCup(cup: Node) {
  79. cup.setParent(this.outNodes);
  80. this.arrangeCups();
  81. }
  82. removeCup(cup: Node) {
  83. cup.removeFromParent();
  84. this.arrangeCups();
  85. }
  86. getCups() {
  87. return this.cups;
  88. }
  89. }