BackgroundManager.ts 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. import { _decorator, Component, Node, Sprite, SpriteFrame, resources, find, assetManager } from 'cc';
  2. import { LevelConfigManager } from './LevelConfigManager';
  3. import { SaveDataManager } from './SaveDataManager';
  4. import EventBus, { GameEvents } from '../Core/EventBus';
  5. import { BundleLoader } from '../Core/BundleLoader';
  6. import { ResourcePreloader } from '../Core/ResourcePreloader';
  7. const { ccclass, property } = _decorator;
  8. /**
  9. * 背景管理器 - 负责根据关卡配置动态设置游戏背景
  10. */
  11. @ccclass('BackgroundManager')
  12. export class BackgroundManager extends Component {
  13. @property(Node)
  14. backgroundNode: Node = null; // Canvas/GameLevelUI/Background节点
  15. private backgroundSprite: Sprite = null;
  16. private levelConfigManager: LevelConfigManager = null;
  17. private saveDataManager: SaveDataManager = null;
  18. private bundleLoader: BundleLoader = null;
  19. private resourcePreloader: ResourcePreloader = null;
  20. onLoad() {
  21. // 获取关卡配置管理器
  22. this.levelConfigManager = LevelConfigManager.getInstance();
  23. // 获取SaveDataManager实例
  24. this.saveDataManager = SaveDataManager.getInstance();
  25. // 获取BundleLoader实例
  26. this.bundleLoader = BundleLoader.getInstance();
  27. // 获取ResourcePreloader实例
  28. this.resourcePreloader = ResourcePreloader.getInstance();
  29. // 监听关卡开始事件
  30. EventBus.getInstance().on(GameEvents.GAME_START, this.onGameStart, this);
  31. }
  32. start() {
  33. this.initBackgroundSprite();
  34. }
  35. /**
  36. * 初始化背景Sprite组件
  37. */
  38. private initBackgroundSprite() {
  39. // 如果编辑器中没有设置backgroundNode,尝试自动查找
  40. if (!this.backgroundNode) {
  41. this.backgroundNode = find('Canvas/GameLevelUI/Background');
  42. if (!this.backgroundNode) {
  43. console.warn('[BackgroundManager] 未找到Canvas/GameLevelUI/Background节点,请检查节点路径');
  44. return;
  45. }
  46. }
  47. // 获取Sprite组件
  48. this.backgroundSprite = this.backgroundNode.getComponent(Sprite);
  49. if (!this.backgroundSprite) {
  50. console.warn('[BackgroundManager] 背景节点上未找到Sprite组件,请为节点添加Sprite组件');
  51. } else {
  52. console.log('[BackgroundManager] 背景Sprite组件初始化成功');
  53. }
  54. }
  55. onDestroy() {
  56. // 移除事件监听
  57. EventBus.getInstance().off(GameEvents.GAME_START, this.onGameStart, this);
  58. }
  59. /**
  60. * 游戏开始时设置背景
  61. */
  62. private async onGameStart() {
  63. await this.setBackgroundForCurrentLevel();
  64. }
  65. /**
  66. * 根据当前关卡设置背景图片
  67. */
  68. public async setBackgroundForCurrentLevel() {
  69. if (!this.levelConfigManager || !this.saveDataManager) {
  70. console.warn('[BackgroundManager] LevelConfigManager或SaveDataManager未初始化');
  71. return;
  72. }
  73. const currentLevel = this.saveDataManager.getCurrentLevel();
  74. const levelConfig = await this.levelConfigManager.getLevelConfig(currentLevel);
  75. console.log(`[BackgroundManager] 当前关卡: ${currentLevel}`);
  76. console.log(`[BackgroundManager] 关卡配置:`, levelConfig);
  77. if (levelConfig && levelConfig.backgroundImage) {
  78. console.log(`[BackgroundManager] 关卡${currentLevel}配置的背景图片: ${levelConfig.backgroundImage}`);
  79. // 转换路径格式:从 "images/LevelBackground/BG1" 转换为 "LevelBackground/BG1"
  80. const bundlePath = levelConfig.backgroundImage.replace('images/', '');
  81. await this.setBackground(bundlePath);
  82. } else {
  83. // 使用默认背景
  84. await this.setBackground('LevelBackground/BG1');
  85. console.log(`[BackgroundManager] 关卡${currentLevel}未配置背景图片,使用默认背景`);
  86. if (levelConfig) {
  87. console.log(`[BackgroundManager] 关卡配置中backgroundImage字段值:`, levelConfig.backgroundImage);
  88. }
  89. }
  90. }
  91. /**
  92. * 设置背景图片
  93. * @param imagePath 图片路径(相对于images Bundle根目录)
  94. */
  95. public async setBackground(imagePath: string) {
  96. if (!this.backgroundSprite) {
  97. console.warn('[BackgroundManager] 背景Sprite组件未找到,无法设置背景');
  98. return;
  99. }
  100. console.log(`[BackgroundManager] 开始设置背景图片: ${imagePath}`);
  101. try {
  102. // 优先使用预加载的资源
  103. let spriteFrame = this.resourcePreloader.getPreloadedBackground(imagePath);
  104. if (!spriteFrame) {
  105. console.log(`[BackgroundManager] 预加载资源未找到,动态加载 ${imagePath}`);
  106. // 如果预加载资源不存在,则动态加载
  107. spriteFrame = await this.bundleLoader.loadSpriteFrame(`${imagePath}/spriteFrame`);
  108. } else {
  109. console.log(`[BackgroundManager] 使用预加载的背景图片 ${imagePath}`);
  110. }
  111. if (spriteFrame && this.backgroundSprite && this.backgroundSprite.isValid) {
  112. this.backgroundSprite.spriteFrame = spriteFrame;
  113. console.log(`[BackgroundManager] 背景图片设置成功: ${imagePath}`);
  114. }
  115. } catch (error) {
  116. console.error(`[BackgroundManager] 背景图片加载失败: ${imagePath}`, error);
  117. // 如果不是默认背景,尝试加载默认背景
  118. if (imagePath !== 'LevelBackground/BG1') {
  119. console.log('[BackgroundManager] 尝试加载默认背景');
  120. await this.setBackground('LevelBackground/BG1');
  121. }
  122. }
  123. }
  124. /**
  125. * 根据指定关卡设置背景图片
  126. * @param levelId 关卡ID
  127. */
  128. public async setBackgroundForLevel(levelId: number) {
  129. if (!this.levelConfigManager) {
  130. console.warn('[BackgroundManager] LevelConfigManager未初始化');
  131. return;
  132. }
  133. const levelConfig = await this.levelConfigManager.getLevelConfig(levelId);
  134. if (levelConfig && levelConfig.backgroundImage) {
  135. // 转换路径格式:从 "images/LevelBackground/BG1" 转换为 "LevelBackground/BG1"
  136. const bundlePath = levelConfig.backgroundImage.replace('images/', '');
  137. await this.setBackground(bundlePath);
  138. } else {
  139. // 使用默认背景
  140. await this.setBackground('LevelBackground/BG1');
  141. console.log(`[BackgroundManager] 关卡${levelId}未配置背景图片,使用默认背景`);
  142. }
  143. }
  144. }