RosterManager.ts 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. import { _decorator, Component, Node, Button, Animation, Sprite, SpriteFrame, resources, assetManager } from 'cc';
  2. const { ccclass, property } = _decorator;
  3. /**
  4. * 名单管理器,控制名单UI的显示和隐藏,并管理学生头像显示
  5. */
  6. @ccclass('RosterManager')
  7. export class RosterManager extends Component {
  8. @property({
  9. type: Node,
  10. tooltip: '名单UI面板'
  11. })
  12. rosterPanel: Node = null;
  13. @property({
  14. type: Button,
  15. tooltip: '关闭按钮'
  16. })
  17. closeButton: Button = null;
  18. @property({
  19. type: Animation,
  20. tooltip: '名单动画组件(可选)'
  21. })
  22. rosterAnimation: Animation = null;
  23. @property({
  24. type: Node,
  25. tooltip: '学生头像容器(可选,用于未来功能)'
  26. })
  27. avatarContainer: Node = null;
  28. @property({
  29. tooltip: '头像资源路径(可选,用于未来功能)'
  30. })
  31. avatarResourcePath: string = "avatars/";
  32. // 保存头像引用的字典,用于未来功能
  33. private avatarMap: Map<string, SpriteFrame> = new Map();
  34. start() {
  35. // 初始化隐藏名单面板
  36. if (this.rosterPanel) {
  37. this.rosterPanel.active = false;
  38. }
  39. // 注册关闭按钮点击事件
  40. this.setupCloseButton();
  41. }
  42. /**
  43. * 设置关闭按钮事件
  44. */
  45. private setupCloseButton() {
  46. if (this.closeButton) {
  47. // 移除可能已存在的事件监听
  48. this.closeButton.node.off('click');
  49. // 使用按钮的点击事件监听方式
  50. this.closeButton.node.on('click', () => {
  51. console.log('名单关闭按钮被点击');
  52. this.hideRosterPanel();
  53. }, this);
  54. console.log('名单关闭按钮事件已注册');
  55. } else {
  56. console.error('名单关闭按钮未设置');
  57. }
  58. }
  59. /**
  60. * 显示名单面板
  61. */
  62. public showRosterPanel() {
  63. if (this.rosterPanel) {
  64. this.rosterPanel.active = true;
  65. // 确保面板在最前面
  66. this.rosterPanel.setSiblingIndex(999);
  67. // 播放打开动画(如果有)
  68. if (this.rosterAnimation) {
  69. this.rosterAnimation.play('roster_open');
  70. }
  71. } else {
  72. console.error('名单面板未设置');
  73. }
  74. }
  75. /**
  76. * 隐藏名单面板
  77. */
  78. public hideRosterPanel() {
  79. console.log('hideRosterPanel被调用');
  80. if (this.rosterPanel) {
  81. // 播放关闭动画,并在动画结束后隐藏面板
  82. if (this.rosterAnimation) {
  83. this.rosterAnimation.play('roster_close');
  84. this.scheduleOnce(() => {
  85. this.rosterPanel.active = false;
  86. console.log('名单面板已隐藏(动画后)');
  87. }, 0.5); // 假设动画时长为0.5秒
  88. } else {
  89. this.rosterPanel.active = false;
  90. console.log('名单面板已隐藏(立即)');
  91. }
  92. }
  93. }
  94. /**
  95. * 预加载头像资源(用于未来功能)
  96. * @param avatarIds 头像ID数组
  97. */
  98. public preloadAvatars(avatarIds: string[]) {
  99. if (!this.avatarContainer) {
  100. return;
  101. }
  102. avatarIds.forEach(id => {
  103. const path = `${this.avatarResourcePath}avatar_${id}`;
  104. resources.load(path, SpriteFrame, (err, spriteFrame) => {
  105. if (err) {
  106. console.error(`加载头像 ${id} 失败:`, err);
  107. return;
  108. }
  109. this.avatarMap.set(id, spriteFrame);
  110. });
  111. });
  112. }
  113. /**
  114. * 显示头像(用于未来功能)
  115. * @param slotId 头像位置ID
  116. * @param avatarId 头像资源ID
  117. */
  118. public showAvatar(slotId: string, avatarId: string) {
  119. if (!this.avatarContainer) {
  120. return;
  121. }
  122. // 查找对应的头像槽位
  123. const avatarSlot = this.avatarContainer.getChildByName(slotId);
  124. if (!avatarSlot) {
  125. console.error(`未找到头像槽位: ${slotId}`);
  126. return;
  127. }
  128. // 获取已加载的头像
  129. const spriteFrame = this.avatarMap.get(avatarId);
  130. if (spriteFrame) {
  131. const sprite = avatarSlot.getComponent(Sprite);
  132. if (sprite) {
  133. sprite.spriteFrame = spriteFrame;
  134. }
  135. } else {
  136. // 如果头像未预加载,则即时加载
  137. const path = `${this.avatarResourcePath}avatar_${avatarId}`;
  138. resources.load(path, SpriteFrame, (err, spriteFrame) => {
  139. if (err) {
  140. console.error(`加载头像 ${avatarId} 失败:`, err);
  141. return;
  142. }
  143. const sprite = avatarSlot.getComponent(Sprite);
  144. if (sprite) {
  145. sprite.spriteFrame = spriteFrame;
  146. // 保存引用以便下次使用
  147. this.avatarMap.set(avatarId, spriteFrame);
  148. }
  149. });
  150. }
  151. }
  152. onDestroy() {
  153. // 移除按钮事件监听
  154. if (this.closeButton) {
  155. this.closeButton.node.off('click');
  156. }
  157. // 清理资源
  158. this.avatarMap.clear();
  159. }
  160. }