123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652 |
- import { _decorator, Component, Node, resources, sp, Asset, Button } from 'cc';
- import { DataManager } from './DataManager';
- import { CharacterManager } from './CharacterManager';
- import { QuestionAnswerManager } from './QuestionAnswerManager';
- import { AvatarManager } from './AvatarManager';
- import { PassCardManager } from './PassCardManager';
- import { PhoneManager } from './PhoneManager';
- import { RosterManager } from './RosterManager';
- import { PersonalInfoManager } from './PersonalInfoManager';
- import { LieDetectorManager } from './LieDetectorManager';
- import { GameLifeManager } from './GameLifeManager';
- import { SummaryManager } from './SummaryManager';
- const { ccclass, property } = _decorator;
- @ccclass('GameFlowManager')
- export class GameFlowManager extends Component {
- @property({
- type: DataManager,
- tooltip: '数据管理器引用'
- })
- dataManager: DataManager = null;
- @property({
- type: CharacterManager,
- tooltip: '角色管理器引用'
- })
- characterManager: CharacterManager = null;
- @property({
- type: QuestionAnswerManager,
- tooltip: '问答管理器引用'
- })
- questionAnswerManager: QuestionAnswerManager = null;
- @property({
- type: Button,
- tooltip: '放行按钮'
- })
- allowButton: Button = null;
- @property({
- type: Button,
- tooltip: '赶走按钮'
- })
- dismissButton: Button = null;
- @property({
- type: AvatarManager,
- tooltip: '头像管理器引用'
- })
- avatarManager: AvatarManager = null;
- @property({
- type: PassCardManager,
- tooltip: '通行证管理器引用'
- })
- passCardManager: PassCardManager = null;
- @property({
- type: PhoneManager,
- tooltip: '电话管理器引用'
- })
- phoneManager: PhoneManager = null;
- @property({
- type: RosterManager,
- tooltip: '名单管理器引用'
- })
- rosterManager: RosterManager = null;
- @property({
- type: PersonalInfoManager,
- tooltip: '个人资料管理器引用'
- })
- personalInfoManager: PersonalInfoManager = null;
- @property({
- type: LieDetectorManager,
- tooltip: '测谎仪管理器引用'
- })
- lieDetectorManager: LieDetectorManager = null;
- @property({
- type: GameLifeManager,
- tooltip: '游戏生命值管理器引用'
- })
- gameLifeManager: GameLifeManager = null;
- @property({
- type: SummaryManager,
- tooltip: '总结管理器引用'
- })
- summaryManager: SummaryManager = null;
- // 当前关卡中的NPC索引
- private currentNpcIndex: number = -1;
-
- // 当前关卡的NPC列表
- private currentNpcs: any[] = [];
- start() {
- // 初始化UI管理器
- this.initUIManagers();
-
- // 注册按钮事件
- this.registerButtonEvents();
-
- // 设置生命值管理器回调
- this.setupLifeManagerCallbacks();
-
- // 开始游戏流程
- this.startGameFlow();
- }
- /**
- * 初始化UI管理器
- */
- private initUIManagers(): void {
- // 检查通行证管理器是否被正确引用
- if (!this.passCardManager) {
- console.error('通行证管理器未设置');
- }
-
- // 检查电话管理器是否被正确引用
- if (!this.phoneManager) {
- console.error('电话管理器未设置');
- }
-
- // 检查名单管理器是否被正确引用
- if (!this.rosterManager) {
- console.error('名单管理器未设置');
- }
-
- // 检查个人资料管理器是否被正确引用
- if (!this.personalInfoManager) {
- console.error('个人资料管理器未设置');
- }
-
- // 检查测谎仪管理器是否被正确引用
- if (!this.lieDetectorManager) {
- console.error('测谎仪管理器未设置');
- }
-
- // 检查生命值管理器是否被正确引用
- if (!this.gameLifeManager) {
- console.error('生命值管理器未设置');
- }
-
- // 检查总结管理器是否被正确引用
- if (!this.summaryManager) {
- console.error('总结管理器未设置');
- }
-
- console.log('所有UI管理器已初始化');
- if (this.summaryManager) {
- this.summaryManager.onShowCharacterDetail = (characterId) => {
- const npcData = this.dataManager.getNPCById(characterId);
- if (!npcData) return;
-
- console.log(`在SummaryManager中显示角色详情: ID=${characterId}, 名称=${npcData.characterName}`);
-
- // 构建完整的角色数据对象
- const characterData = this.buildCharacterInfoData(npcData);
-
- this.personalInfoManager.displayCharacterInfo(characterData);
- };
- }
- }
- /**
- * 注册按钮事件
- */
- private registerButtonEvents(): void {
- // 注册放行按钮点击事件
- if (this.allowButton) {
- this.allowButton.node.on(Button.EventType.CLICK, this.handleCharacterPassed, this);
- } else {
- console.error('放行按钮未设置');
- }
-
- // 注册赶走按钮点击事件
- if (this.dismissButton) {
- this.dismissButton.node.on(Button.EventType.CLICK, this.handleCharacterDismissed, this);
- } else {
- console.error('赶走按钮未设置');
- }
- }
- /**
- * 设置生命值管理器回调
- */
- private setupLifeManagerCallbacks(): void {
- if (this.gameLifeManager) {
- this.gameLifeManager.setCallbacks(
- // 复活后的回调,继续游戏流程
- () => {
- console.log('玩家已复活,继续游戏');
- // 重新启用按钮
- this.enableButtons();
- },
- // 游戏结束的回调,显示当天总结
- () => {
- console.log('游戏结束,显示当天总结');
- // 禁用按钮
- this.disableButtons();
- }
- );
- }
- }
- /**
- * 重新开始游戏流程
- * 在切换关卡后调用此方法重新开始游戏
- */
- public restartGameFlow(): void {
- console.log('GameFlowManager.restartGameFlow被调用,重新开始游戏流程');
-
- // 重置NPC索引
- this.currentNpcIndex = -1;
-
- // 获取新关卡数据
- const currentLevel = this.dataManager.getCurrentLevel();
- if (!currentLevel) {
- console.error('无法获取当前关卡数据');
- return;
- }
-
- console.log(`开始关卡: ${currentLevel.name}`);
-
- // 从关卡NPC列表中随机选择NPC
- this.setupRandomNpcs(currentLevel);
-
- // 如果有生命值管理器,重置状态和生命值
- if (this.gameLifeManager) {
- // 重置总结面板显示状态
- this.gameLifeManager.resetSummaryPanelState();
-
- // 重置生命值
- this.gameLifeManager.resetLife();
- }
-
- // 显示第一个NPC
- this.showNextNpc();
- }
-
- /**
- * 从关卡NPC列表中随机选择NPC
- * @param levelData 关卡数据
- */
- private setupRandomNpcs(levelData: any): void {
- if (!levelData || !levelData.npcs || !Array.isArray(levelData.npcs)) {
- console.error('关卡数据中缺少有效的NPC列表');
- this.currentNpcs = [];
- return;
- }
-
- // 获取原始NPC列表的副本
- const allNpcs = [...levelData.npcs];
-
- // 打乱NPC顺序
- this.shuffleArray(allNpcs);
-
- // 获取要选择的NPC数量
- const randomNpcCount = levelData.randomNpcCount || allNpcs.length;
- console.log(`本关卡需要随机选择 ${randomNpcCount} 个角色`);
-
- // 选择指定数量的NPC
- this.currentNpcs = allNpcs.slice(0, randomNpcCount);
-
- console.log(`已随机选择 ${this.currentNpcs.length} 个角色`);
- }
-
- /**
- * 随机打乱数组顺序
- * @param array 要打乱的数组
- */
- private shuffleArray(array: any[]): void {
- for (let i = array.length - 1; i > 0; i--) {
- // 生成随机索引
- const j = Math.floor(Math.random() * (i + 1));
- // 交换元素
- [array[i], array[j]] = [array[j], array[i]];
- }
- }
- /**
- * 开始游戏流程
- */
- private startGameFlow(): void {
- // 获取当前关卡数据
- const currentLevel = this.dataManager.getCurrentLevel();
- if (!currentLevel) {
- console.error('无法获取当前关卡数据');
- return;
- }
- console.log(`开始关卡: ${currentLevel.name}`);
-
- // 从关卡NPC列表中随机选择NPC
- this.setupRandomNpcs(currentLevel);
-
- // 显示第一个NPC
- this.showNextNpc();
- }
- /**
- * 显示下一个NPC
- */
- public showNextNpc(): void {
- // 如果已经显示了总结面板,不再继续处理NPC
- if (this.gameLifeManager && this.gameLifeManager.hasSummaryPanelShown()) {
- console.log('总结面板已显示,不再继续处理NPC');
- return;
- }
-
- this.currentNpcIndex++;
-
- // 检查是否还有NPC
- if (this.currentNpcIndex >= this.currentNpcs.length) {
- console.log('当前关卡所有NPC已处理完毕');
- // 显示总结面板
- if (this.summaryManager) {
- if (this.gameLifeManager) {
- this.gameLifeManager.showSummaryPanel();
- } else {
- this.summaryManager.showSummaryPanel();
- }
- }
- return;
- }
-
- // 获取当前NPC数据
- const npc = this.currentNpcs[this.currentNpcIndex];
-
- // 配置问答对
- this.setupQuestionAnswers(npc.qaPairs);
-
- // 如果有头像管理器,先加载头像
- if (this.avatarManager) {
- this.avatarManager.loadAvatar(npc.characterId);
- }
-
- // 配置角色外观,并在完成后让角色入场
- this.characterManager.setupCharacterAppearance(npc.characterId, npc.skinName, () => {
- // 让角色入场(只有在外观设置完成后才执行)
- this.characterManager.characterEnter();
-
- // 启用按钮
- this.enableButtons();
- });
- }
- /**
- * 启用决策按钮
- */
- private enableButtons(): void {
- if (this.allowButton) {
- this.allowButton.interactable = true;
- }
-
- if (this.dismissButton) {
- this.dismissButton.interactable = true;
- }
- }
-
- /**
- * 禁用决策按钮
- */
- private disableButtons(): void {
- if (this.allowButton) {
- this.allowButton.interactable = false;
- }
-
- if (this.dismissButton) {
- this.dismissButton.interactable = false;
- }
- }
- /**
- * 设置问答对
- * @param qaPairs 问答对数组
- */
- private setupQuestionAnswers(qaPairs: any[]): void {
- if (!this.questionAnswerManager) {
- console.error('问答管理器未设置');
- return;
- }
-
- // 替换所有问答对(而不是添加)
- this.questionAnswerManager.replaceAllQuestionAnswers(qaPairs);
- }
- /**
- * 处理放行角色
- */
- public handleCharacterPassed(): void {
- // 禁用按钮,防止连续点击
- this.disableButtons();
-
- // 获取当前NPC数据
- const npcData = this.getCurrentNpcData();
-
- // 记录放行统计
- if (this.summaryManager && npcData) {
- this.summaryManager.recordPassedNPC(npcData);
- }
-
- // 检查是否放行了假角色,如果是则扣除生命值
- if (npcData && npcData.type === 'fake') {
- console.log('错误:放行了伪装者');
- if (this.gameLifeManager) {
- this.gameLifeManager.decreaseLife(1);
-
- // 如果生命值为0,则不继续游戏流程,等待失败面板处理
- if (this.gameLifeManager.getCurrentLife() <= 0) {
- return;
- }
- }
- }
-
- // 让角色向右移动,动画完成后显示下一个NPC
- this.characterManager.moveCharacterRight(() => {
- this.showNextNpc();
- });
- }
- /**
- * 处理赶走角色
- */
- public handleCharacterDismissed(): void {
- // 禁用按钮,防止连续点击
- this.disableButtons();
-
- // 获取当前NPC数据
- const npcData = this.getCurrentNpcData();
-
- // 记录驱赶统计
- if (this.summaryManager && npcData) {
- this.summaryManager.recordDismissedNPC(npcData);
- }
-
- // 检查是否赶走了真角色,如果是则扣除生命值
- if (npcData && npcData.type === 'real') {
- console.log('错误:赶走了真实角色');
- if (this.gameLifeManager) {
- this.gameLifeManager.decreaseLife(1);
-
- // 如果生命值为0,则不继续游戏流程,等待失败面板处理
- if (this.gameLifeManager.getCurrentLife() <= 0) {
- return;
- }
- }
- }
-
- // 让角色向左移动,动画完成后显示下一个NPC
- this.characterManager.moveCharacterLeft(() => {
- this.showNextNpc();
- });
- }
- /**
- * 获取当前NPC数据
- * @returns 当前NPC数据,如果没有则返回null
- */
- public getCurrentNpcData(): any {
- if (this.currentNpcIndex < 0 || this.currentNpcIndex >= this.currentNpcs.length) {
- return null;
- }
-
- return this.currentNpcs[this.currentNpcIndex];
- }
- /**
- * 获取通行证管理器
- * @returns 通行证管理器实例
- */
- public getPassCardManager(): PassCardManager {
- return this.passCardManager;
- }
- /**
- * 获取电话管理器
- * @returns 电话管理器实例
- */
- public getPhoneManager(): PhoneManager {
- return this.phoneManager;
- }
- /**
- * 获取名单管理器
- * @returns 名单管理器实例
- */
- public getRosterManager(): RosterManager {
- return this.rosterManager;
- }
-
- /**
- * 获取个人资料管理器
- * @returns 个人资料管理器实例
- */
- public getPersonalInfoManager(): PersonalInfoManager {
- return this.personalInfoManager;
- }
-
- /**
- * 获取测谎仪管理器
- * @returns 测谎仪管理器实例
- */
- public getLieDetectorManager(): LieDetectorManager {
- return this.lieDetectorManager;
- }
-
- /**
- * 显示通行证
- * @param passData 通行证数据
- */
- public showPassCard(passData: any): void {
- if (this.passCardManager) {
- this.passCardManager.showPassCard(passData);
- } else {
- console.error('通行证管理器未设置,无法显示通行证');
- }
- }
-
- /**
- * 显示电话对话框
- */
- public showPhoneUI(): void {
- if (this.phoneManager) {
- this.phoneManager.showPhonePanel();
- } else {
- console.error('电话管理器未设置,无法显示电话UI');
- }
- }
-
- /**
- * 显示名单面板
- */
- public showRosterPanel(): void {
- if (this.rosterManager) {
- // 获取今日名单数据并传递给RosterManager
- // 确保名单数据符合TodayListItem接口 (包含name和avatarPath属性)
- const todayList = this.dataManager.getTodayList();
- console.log(`获取到今日名单数据,共${todayList.length}条记录`);
-
- // 设置名单数据并显示
- this.rosterManager.setTodayList(todayList);
- this.rosterManager.showRosterPanel();
- } else {
- console.error('名单管理器未设置,无法显示名单面板');
- }
- }
- /**
- * 获取当前关卡名单数据并显示
- * 此方法已弃用,请直接使用showRosterPanel
- * @deprecated
- */
- public showCurrentLevelRoster(): void {
- this.showRosterPanel();
- }
- /**
- * 显示当前NPC的个人资料
- */
- public showCurrentNpcPersonalInfo(): void {
- // 获取当前NPC数据
- const npcData = this.getCurrentNpcData();
- if (!npcData) {
- console.error('无法获取当前NPC数据');
- return;
- }
-
- console.log(`显示当前NPC资料: ID=${npcData.characterId}, 名称=${npcData.characterName}`);
-
- // 确保PersonalInfoManager已设置
- if (this.personalInfoManager) {
- // 构建完整的角色数据对象
- const characterData = this.buildCharacterInfoData(npcData);
-
- // 显示个人资料
- this.personalInfoManager.displayCharacterInfo(characterData);
- } else {
- console.error('个人资料管理器未设置');
- }
- }
-
- /**
- * 构建完整的角色信息数据对象
- * @param npcData 原始NPC数据
- * @returns 格式化后的角色信息对象
- */
- private buildCharacterInfoData(npcData: any): any {
- const passInfo = npcData.pass || {};
- const personalInfo = npcData.personal || {};
-
- // 构建角色数据对象
- return {
- characterId: npcData.characterId,
- characterName: npcData.characterName,
- info: personalInfo.info || "无个人资料",
- avatarPath: personalInfo.avatarPath || `avatars/${npcData.characterId}/avatar_${npcData.characterId}_5`,
- room: passInfo.room || "",
- identityId: passInfo.identityId || personalInfo.id || "",
- hasRoommate: personalInfo.hasRoommate || false,
- roommateInfo: personalInfo.hasRoommate && personalInfo.roommate ?
- (personalInfo.roommate.id || '未知') : null
- };
- }
- /**
- * 显示测谎仪面板
- */
- public showLieDetectorPanel(): void {
- // 获取当前NPC数据
- const npcData = this.getCurrentNpcData();
- if (!npcData) {
- console.error('无法获取当前NPC数据');
- return;
- }
-
- // 设置测谎仪状态并显示
- if (this.lieDetectorManager) {
- // 从NPC数据中获取是否为伪装者的状态
- const isFake = npcData.type === 'fake';
-
- // 设置当前角色状态
- this.lieDetectorManager.setCharacterStatus(isFake);
-
- // 显示测谎仪面板
- this.lieDetectorManager.showLieDetectorPanel();
- } else {
- console.error('测谎仪管理器未设置');
- }
- }
- /**
- * 组件销毁时清理事件监听
- */
- onDestroy() {
- // 移除按钮事件监听
- if (this.allowButton) {
- this.allowButton.node.off(Button.EventType.CLICK, this.handleCharacterPassed, this);
- }
-
- if (this.dismissButton) {
- this.dismissButton.node.off(Button.EventType.CLICK, this.handleCharacterDismissed, this);
- }
- }
- }
|