GameFlowManager.ts 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. import { _decorator, Component, Node, resources, sp, Asset, Button } from 'cc';
  2. import { DataManager } from './DataManager';
  3. import { CharacterManager } from './CharacterManager';
  4. import { QuestionAnswerManager } from './QuestionAnswerManager';
  5. import { AvatarManager } from './AvatarManager';
  6. import { PassCardManager } from './PassCardManager';
  7. import { PhoneManager } from './PhoneManager';
  8. import { RosterManager } from './RosterManager';
  9. import { PersonalInfoManager } from './PersonalInfoManager';
  10. import { LieDetectorManager } from './LieDetectorManager';
  11. const { ccclass, property } = _decorator;
  12. @ccclass('GameFlowManager')
  13. export class GameFlowManager extends Component {
  14. @property({
  15. type: DataManager,
  16. tooltip: '数据管理器引用'
  17. })
  18. dataManager: DataManager = null;
  19. @property({
  20. type: CharacterManager,
  21. tooltip: '角色管理器引用'
  22. })
  23. characterManager: CharacterManager = null;
  24. @property({
  25. type: QuestionAnswerManager,
  26. tooltip: '问答管理器引用'
  27. })
  28. questionAnswerManager: QuestionAnswerManager = null;
  29. @property({
  30. type: Button,
  31. tooltip: '放行按钮'
  32. })
  33. allowButton: Button = null;
  34. @property({
  35. type: Button,
  36. tooltip: '赶走按钮'
  37. })
  38. dismissButton: Button = null;
  39. @property({
  40. type: AvatarManager,
  41. tooltip: '头像管理器引用'
  42. })
  43. avatarManager: AvatarManager = null;
  44. @property({
  45. type: PassCardManager,
  46. tooltip: '通行证管理器引用'
  47. })
  48. passCardManager: PassCardManager = null;
  49. @property({
  50. type: PhoneManager,
  51. tooltip: '电话管理器引用'
  52. })
  53. phoneManager: PhoneManager = null;
  54. @property({
  55. type: RosterManager,
  56. tooltip: '名单管理器引用'
  57. })
  58. rosterManager: RosterManager = null;
  59. @property({
  60. type: PersonalInfoManager,
  61. tooltip: '个人资料管理器引用'
  62. })
  63. personalInfoManager: PersonalInfoManager = null;
  64. @property({
  65. type: LieDetectorManager,
  66. tooltip: '测谎仪管理器引用'
  67. })
  68. lieDetectorManager: LieDetectorManager = null;
  69. // 当前关卡中的NPC索引
  70. private currentNpcIndex: number = -1;
  71. // 当前关卡的NPC列表
  72. private currentNpcs: any[] = [];
  73. start() {
  74. // 初始化UI管理器
  75. this.initUIManagers();
  76. // 注册按钮事件
  77. this.registerButtonEvents();
  78. // 开始游戏流程
  79. this.startGameFlow();
  80. }
  81. /**
  82. * 初始化UI管理器
  83. */
  84. private initUIManagers(): void {
  85. // 检查通行证管理器是否被正确引用
  86. if (!this.passCardManager) {
  87. console.error('通行证管理器未设置');
  88. }
  89. // 检查电话管理器是否被正确引用
  90. if (!this.phoneManager) {
  91. console.error('电话管理器未设置');
  92. }
  93. // 检查名单管理器是否被正确引用
  94. if (!this.rosterManager) {
  95. console.error('名单管理器未设置');
  96. }
  97. // 检查个人资料管理器是否被正确引用
  98. if (!this.personalInfoManager) {
  99. console.error('个人资料管理器未设置');
  100. }
  101. // 检查测谎仪管理器是否被正确引用
  102. if (!this.lieDetectorManager) {
  103. console.error('测谎仪管理器未设置');
  104. }
  105. console.log('所有UI管理器已初始化');
  106. }
  107. /**
  108. * 注册按钮事件
  109. */
  110. private registerButtonEvents(): void {
  111. // 注册放行按钮点击事件
  112. if (this.allowButton) {
  113. this.allowButton.node.on(Button.EventType.CLICK, this.handleCharacterPassed, this);
  114. } else {
  115. console.error('放行按钮未设置');
  116. }
  117. // 注册赶走按钮点击事件
  118. if (this.dismissButton) {
  119. this.dismissButton.node.on(Button.EventType.CLICK, this.handleCharacterDismissed, this);
  120. } else {
  121. console.error('赶走按钮未设置');
  122. }
  123. }
  124. /**
  125. * 开始游戏流程
  126. */
  127. private startGameFlow(): void {
  128. // 获取当前关卡数据
  129. const currentLevel = this.dataManager.getCurrentLevel();
  130. if (!currentLevel) {
  131. console.error('无法获取当前关卡数据');
  132. return;
  133. }
  134. console.log(`开始关卡: ${currentLevel.name}`);
  135. // 获取当前关卡的NPC列表
  136. this.currentNpcs = currentLevel.npcs;
  137. // 重置NPC索引
  138. this.currentNpcIndex = -1;
  139. // 显示第一个NPC
  140. this.showNextNpc();
  141. }
  142. /**
  143. * 显示下一个NPC
  144. */
  145. public showNextNpc(): void {
  146. this.currentNpcIndex++;
  147. // 检查是否还有NPC
  148. if (this.currentNpcIndex >= this.currentNpcs.length) {
  149. console.log('当前关卡所有NPC已处理完毕');
  150. // 可以在这里添加关卡完成逻辑
  151. return;
  152. }
  153. // 获取当前NPC数据
  154. const npc = this.currentNpcs[this.currentNpcIndex];
  155. // 配置问答对
  156. this.setupQuestionAnswers(npc.qaPairs);
  157. // 如果有头像管理器,先加载头像
  158. if (this.avatarManager) {
  159. this.avatarManager.loadAvatar(npc.characterId);
  160. }
  161. // 配置角色外观,并在完成后让角色入场
  162. this.characterManager.setupCharacterAppearance(npc.characterId, npc.skinName, () => {
  163. // 让角色入场(只有在外观设置完成后才执行)
  164. this.characterManager.characterEnter();
  165. // 启用按钮
  166. this.enableButtons();
  167. });
  168. }
  169. /**
  170. * 启用决策按钮
  171. */
  172. private enableButtons(): void {
  173. if (this.allowButton) {
  174. this.allowButton.interactable = true;
  175. }
  176. if (this.dismissButton) {
  177. this.dismissButton.interactable = true;
  178. }
  179. }
  180. /**
  181. * 禁用决策按钮
  182. */
  183. private disableButtons(): void {
  184. if (this.allowButton) {
  185. this.allowButton.interactable = false;
  186. }
  187. if (this.dismissButton) {
  188. this.dismissButton.interactable = false;
  189. }
  190. }
  191. /**
  192. * 设置问答对
  193. * @param qaPairs 问答对数组
  194. */
  195. private setupQuestionAnswers(qaPairs: any[]): void {
  196. if (!this.questionAnswerManager) {
  197. console.error('问答管理器未设置');
  198. return;
  199. }
  200. // 替换所有问答对(而不是添加)
  201. this.questionAnswerManager.replaceAllQuestionAnswers(qaPairs);
  202. }
  203. /**
  204. * 处理放行角色
  205. */
  206. public handleCharacterPassed(): void {
  207. // 禁用按钮,防止连续点击
  208. this.disableButtons();
  209. // 让角色向右移动,动画完成后显示下一个NPC
  210. this.characterManager.moveCharacterRight(() => {
  211. this.showNextNpc();
  212. });
  213. }
  214. /**
  215. * 处理赶走角色
  216. */
  217. public handleCharacterDismissed(): void {
  218. // 禁用按钮,防止连续点击
  219. this.disableButtons();
  220. // 让角色向左移动,动画完成后显示下一个NPC
  221. this.characterManager.moveCharacterLeft(() => {
  222. this.showNextNpc();
  223. });
  224. }
  225. /**
  226. * 获取当前NPC数据
  227. * @returns 当前NPC数据,如果没有则返回null
  228. */
  229. public getCurrentNpcData(): any {
  230. if (this.currentNpcIndex < 0 || this.currentNpcIndex >= this.currentNpcs.length) {
  231. return null;
  232. }
  233. return this.currentNpcs[this.currentNpcIndex];
  234. }
  235. /**
  236. * 获取通行证管理器
  237. * @returns 通行证管理器实例
  238. */
  239. public getPassCardManager(): PassCardManager {
  240. return this.passCardManager;
  241. }
  242. /**
  243. * 获取电话管理器
  244. * @returns 电话管理器实例
  245. */
  246. public getPhoneManager(): PhoneManager {
  247. return this.phoneManager;
  248. }
  249. /**
  250. * 获取名单管理器
  251. * @returns 名单管理器实例
  252. */
  253. public getRosterManager(): RosterManager {
  254. return this.rosterManager;
  255. }
  256. /**
  257. * 获取个人资料管理器
  258. * @returns 个人资料管理器实例
  259. */
  260. public getPersonalInfoManager(): PersonalInfoManager {
  261. return this.personalInfoManager;
  262. }
  263. /**
  264. * 获取测谎仪管理器
  265. * @returns 测谎仪管理器实例
  266. */
  267. public getLieDetectorManager(): LieDetectorManager {
  268. return this.lieDetectorManager;
  269. }
  270. /**
  271. * 显示通行证
  272. * @param passData 通行证数据
  273. */
  274. public showPassCard(passData: any): void {
  275. if (this.passCardManager) {
  276. this.passCardManager.showPassCard(passData);
  277. } else {
  278. console.error('通行证管理器未设置,无法显示通行证');
  279. }
  280. }
  281. /**
  282. * 显示电话对话框
  283. */
  284. public showPhoneUI(): void {
  285. if (this.phoneManager) {
  286. this.phoneManager.showPhonePanel();
  287. } else {
  288. console.error('电话管理器未设置,无法显示电话UI');
  289. }
  290. }
  291. /**
  292. * 显示名单面板
  293. */
  294. public showRosterPanel(): void {
  295. if (this.rosterManager) {
  296. this.rosterManager.showRosterPanel();
  297. } else {
  298. console.error('名单管理器未设置,无法显示名单面板');
  299. }
  300. }
  301. /**
  302. * 获取当前关卡名单数据并显示
  303. */
  304. public showCurrentLevelRoster(): void {
  305. console.log("准备显示角色名单...");
  306. // 1. 从DataManager获取当前关卡数据
  307. const currentLevel = this.dataManager.getCurrentLevel();
  308. console.log("当前关卡数据:", currentLevel);
  309. if (!currentLevel || !currentLevel.npcs) {
  310. console.error('无法获取当前关卡数据');
  311. return;
  312. }
  313. // 2. 构建人员数据,包括完整的头像路径
  314. const personnelData = currentLevel.npcs.map(npc => {
  315. return {
  316. name: npc.characterName,
  317. avatarPath: `avatars/${npc.characterId}/avatar_${npc.characterId}_5/spriteFrame` // 第5张头像
  318. };
  319. });
  320. console.log("构建的人员数据:", personnelData);
  321. // 3. 调用RosterManager显示数据
  322. if (this.rosterManager) {
  323. console.log("RosterManager存在,准备显示人员列表");
  324. this.rosterManager.displayLevelPersonnel(personnelData);
  325. this.rosterManager.showRosterPanel();
  326. } else {
  327. console.error('名单管理器未设置,无法显示名单');
  328. }
  329. }
  330. /**
  331. * 显示当前NPC的个人资料
  332. */
  333. public showCurrentNpcPersonalInfo(): void {
  334. // 获取当前NPC数据
  335. const npcData = this.getCurrentNpcData();
  336. if (!npcData) {
  337. console.error('无法获取当前NPC数据');
  338. return;
  339. }
  340. // 显示个人资料
  341. if (this.personalInfoManager) {
  342. this.personalInfoManager.displayCharacterInfo({
  343. characterId: npcData.characterId,
  344. info: npcData.personal?.info || "无个人资料",
  345. avatarPath: `avatars/${npcData.characterId}/avatar_${npcData.characterId}_5/spriteFrame`
  346. });
  347. } else {
  348. console.error('个人资料管理器未设置');
  349. }
  350. }
  351. /**
  352. * 显示测谎仪面板
  353. */
  354. public showLieDetectorPanel(): void {
  355. // 获取当前NPC数据
  356. const npcData = this.getCurrentNpcData();
  357. if (!npcData) {
  358. console.error('无法获取当前NPC数据');
  359. return;
  360. }
  361. // 设置测谎仪状态并显示
  362. if (this.lieDetectorManager) {
  363. // 从NPC数据中获取是否为伪装者的状态
  364. const isFake = npcData.type === 'fake';
  365. // 设置当前角色状态
  366. this.lieDetectorManager.setCharacterStatus(isFake);
  367. // 显示测谎仪面板
  368. this.lieDetectorManager.showLieDetectorPanel();
  369. } else {
  370. console.error('测谎仪管理器未设置');
  371. }
  372. }
  373. /**
  374. * 组件销毁时清理事件监听
  375. */
  376. onDestroy() {
  377. // 移除按钮事件监听
  378. if (this.allowButton) {
  379. this.allowButton.node.off(Button.EventType.CLICK, this.handleCharacterPassed, this);
  380. }
  381. if (this.dismissButton) {
  382. this.dismissButton.node.off(Button.EventType.CLICK, this.handleCharacterDismissed, this);
  383. }
  384. }
  385. }