NewbieGuideManager.ts 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. import { _decorator, director, find } from 'cc';
  2. import { SaveDataManager } from '../LevelSystem/SaveDataManager';
  3. import EventBus, { GameEvents } from './EventBus';
  4. import { Audio, AudioManager } from '../AudioManager/AudioManager';
  5. import { GuideUIController } from '../../NewbieGuidePlugin-v1.0.0/NewbieGuidePlugin-v1.0.0/scripts/GuideUIController';
  6. const { ccclass } = _decorator;
  7. /**
  8. * 新手引导管理器
  9. * 负责管理新手引导的状态和自动触发机制
  10. */
  11. @ccclass('NewbieGuideManager')
  12. export class NewbieGuideManager {
  13. private static _instance: NewbieGuideManager;
  14. private saveDataManager: SaveDataManager;
  15. private isInProgress: boolean = false;
  16. private hasCheckedOnSceneLoad: boolean = false;
  17. private constructor() {
  18. this.saveDataManager = SaveDataManager.getInstance();
  19. this.setupEventListeners();
  20. }
  21. public static getInstance(): NewbieGuideManager {
  22. if (!NewbieGuideManager._instance) {
  23. NewbieGuideManager._instance = new NewbieGuideManager();
  24. }
  25. return NewbieGuideManager._instance;
  26. }
  27. /**
  28. * 设置事件监听器
  29. */
  30. private setupEventListeners(): void {
  31. // 监听游戏开始事件,检查是否需要启动新手引导
  32. EventBus.getInstance().on(GameEvents.GAME_START, this.onGameStart, this);
  33. }
  34. /**
  35. * 在GameLevel场景加载时检查并自动启动新手引导
  36. * 这个方法应该在MainUIController的onLoad中调用
  37. */
  38. public checkAndStartNewbieGuideOnSceneLoad(): void {
  39. // 每次场景加载都重新评估引导状态,避免状态在后续关卡残留
  40. console.log('[NewbieGuideManager] 场景加载时检查新手引导状态');
  41. const currentLevel = this.saveDataManager?.getCurrentLevel?.() ?? 1;
  42. if (currentLevel === 1) {
  43. console.log('[NewbieGuideManager] 读取第1关,启动新手引导流程');
  44. this.startNewbieGuide();
  45. } else {
  46. this.isInProgress = false;
  47. console.log('[NewbieGuideManager] 非第1关,关闭新手引导');
  48. // 确保引导遮罩与层级被关闭,避免残留阻挡
  49. try {
  50. const guideMaskAreas = find('Canvas/GuideMaskAreas');
  51. if (guideMaskAreas) {
  52. guideMaskAreas.active = false;
  53. console.log('[NewbieGuideManager] 已隐藏Canvas/GuideMaskAreas');
  54. }
  55. const guideLayer = find('Canvas/GuideLayer');
  56. if (guideLayer) {
  57. guideLayer.active = false;
  58. console.log('[NewbieGuideManager] 已隐藏Canvas/GuideLayer');
  59. }
  60. } catch (e) {
  61. console.warn('[NewbieGuideManager] 隐藏引导遮罩层失败:', e);
  62. }
  63. }
  64. }
  65. /**
  66. * 启动新手引导流程
  67. */
  68. private startNewbieGuide(): void {
  69. this.isInProgress = true;
  70. console.log('[NewbieGuideManager] 新手引导开始,自动触发战斗流程');
  71. // 确保主界面音乐已停止
  72. Audio.stopMusic();
  73. console.log('[NewbieGuideManager] 已停止主界面音乐');
  74. // 立即触发战斗流程
  75. this.triggerBattleFlow();
  76. }
  77. /**
  78. * 检查用户是否是新用户(第一次游戏)
  79. * @returns true表示是新用户,需要新手引导
  80. */
  81. public isNewUser(): boolean {
  82. // 重写显示逻辑:仅当当前关卡为第1关时视为需要新手引导
  83. if (!this.saveDataManager || typeof this.saveDataManager.getCurrentLevel !== 'function') return false;
  84. const currentLevel = this.saveDataManager.getCurrentLevel();
  85. return currentLevel === 1;
  86. }
  87. /**
  88. * 检查玩家是否是新手(第一次游戏)
  89. * @returns true表示是新手,需要新手引导
  90. */
  91. public isNewPlayer(): boolean {
  92. if (!this.saveDataManager) {
  93. console.warn('[NewbieGuideManager] SaveDataManager未初始化');
  94. return false;
  95. }
  96. const playerData = this.saveDataManager.getPlayerData();
  97. // 检查是否有新手引导完成标记
  98. if (playerData.settings && playerData.settings.newbieGuideCompleted !== undefined) {
  99. return !playerData.settings.newbieGuideCompleted;
  100. }
  101. // 如果没有设置,检查其他指标判断是否是新手
  102. // 比如当前关卡是否为1,总游戏时间是否为0等
  103. const isNewbie = playerData.currentLevel === 1 &&
  104. playerData.statistics.totalPlayTime === 0 &&
  105. playerData.statistics.totalGamesPlayed === 0;
  106. console.log('[NewbieGuideManager] 新手检查结果:', {
  107. currentLevel: playerData.currentLevel,
  108. totalPlayTime: playerData.statistics.totalPlayTime,
  109. totalGamesPlayed: playerData.statistics.totalGamesPlayed,
  110. isNewbie: isNewbie
  111. });
  112. return isNewbie;
  113. }
  114. /**
  115. * 标记新手引导已完成
  116. */
  117. public markNewbieGuideCompleted(): void {
  118. if (!this.saveDataManager) {
  119. console.warn('[NewbieGuideManager] SaveDataManager未初始化');
  120. return;
  121. }
  122. const playerData = this.saveDataManager.getPlayerData();
  123. if (!playerData.settings) {
  124. playerData.settings = {
  125. soundEnabled: true,
  126. musicEnabled: true,
  127. soundVolume: 0.8,
  128. musicVolume: 0.6,
  129. vibrationEnabled: true,
  130. autoSaveEnabled: true,
  131. language: 'zh-CN',
  132. graphics: 'medium',
  133. newbieGuideCompleted: false
  134. };
  135. }
  136. playerData.settings.newbieGuideCompleted = true;
  137. this.saveDataManager.savePlayerData(true);
  138. this.isInProgress = false;
  139. console.log('[NewbieGuideManager] 新手引导已标记为完成');
  140. }
  141. /**
  142. * 重置新手引导状态(用于测试)
  143. */
  144. public resetNewbieGuideStatus(): void {
  145. if (!this.saveDataManager) {
  146. console.warn('[NewbieGuideManager] SaveDataManager未初始化');
  147. return;
  148. }
  149. const playerData = this.saveDataManager.getPlayerData();
  150. if (!playerData.settings) {
  151. playerData.settings = {
  152. soundEnabled: true,
  153. musicEnabled: true,
  154. soundVolume: 0.8,
  155. musicVolume: 0.6,
  156. vibrationEnabled: true,
  157. autoSaveEnabled: true,
  158. language: 'zh-CN',
  159. graphics: 'medium',
  160. newbieGuideCompleted: false
  161. };
  162. }
  163. playerData.settings.newbieGuideCompleted = false;
  164. this.saveDataManager.savePlayerData();
  165. console.log('[NewbieGuideManager] 新手引导状态已重置');
  166. }
  167. /**
  168. * 检查当前是否正在进行新手引导
  169. */
  170. public isNewbieGuideInProgress(): boolean {
  171. return this.isInProgress;
  172. }
  173. /**
  174. * 自动触发战斗流程
  175. * 模拟玩家点击战斗按钮的行为
  176. */
  177. private triggerBattleFlow(): void {
  178. console.log('[NewbieGuideManager] 新手引导:自动触发战斗流程');
  179. // 发送新手引导开始事件
  180. EventBus.getInstance().emit('NEWBIE_GUIDE_BATTLE_START');
  181. // 这里我们不直接调用MainUIController的onBattle方法
  182. // 而是通过事件系统通知MainUIController执行战斗流程
  183. // 这样可以保持代码的解耦
  184. //
  185. // 注意:音频播放控制已移除,现在由IN_game.ts的UI显隐控制统一管理
  186. // 当GameLevelUI显示时会自动播放战斗音乐,当MainUI显示时会自动播放主界面音乐
  187. }
  188. /**
  189. * 游戏开始时的处理逻辑
  190. */
  191. private onGameStart(): void {
  192. console.log('[NewbieGuideManager] 游戏开始,检查新手引导状态');
  193. if (this.isNewUser() && !this.isInProgress) {
  194. console.log('[NewbieGuideManager] 检测到新用户,但新手引导未启动,这可能是正常游戏流程');
  195. }
  196. // 如果是新手引导模式,启动GuideUIController
  197. if (this.isInProgress) {
  198. this.startGuideUIController();
  199. }
  200. }
  201. /**
  202. * 启动GuideUIController
  203. */
  204. private startGuideUIController(): void {
  205. console.log('[NewbieGuideManager] 启动GuideUIController');
  206. // 查找Canvas上的GuideUIController组件
  207. const canvas = find('Canvas');
  208. if (!canvas) {
  209. console.warn('[NewbieGuideManager] 未找到Canvas节点');
  210. return;
  211. }
  212. const guideUIController = canvas.getComponent(GuideUIController);
  213. if (!guideUIController) {
  214. console.warn('[NewbieGuideManager] Canvas上未找到GuideUIController组件');
  215. return;
  216. }
  217. // 启动引导序列
  218. guideUIController.startGuideSequence();
  219. console.log('[NewbieGuideManager] GuideUIController已启动');
  220. }
  221. /**
  222. * 获取新手引导进度
  223. * 可以用于显示引导进度或判断引导阶段
  224. */
  225. public getNewbieGuideProgress(): number {
  226. if (!this.isInProgress) {
  227. return this.isNewPlayer() ? 0 : 100;
  228. }
  229. // 这里可以根据具体的引导步骤来计算进度
  230. // 暂时返回50表示正在进行中
  231. return 50;
  232. }
  233. }