NewbieGuideManager.ts 9.5 KB

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