|
@@ -0,0 +1,878 @@
|
|
|
+import { _decorator, Component, Node, Label, Button, Sprite, SpriteFrame, resources, instantiate, UIOpacity, Widget, UITransform, director, Canvas, AssetManager } from 'cc';
|
|
|
+import { DataManager } from './DataManager';
|
|
|
+import { GameFlowManager } from './GameFlowManager';
|
|
|
+
|
|
|
+const { ccclass, property } = _decorator;
|
|
|
+
|
|
|
+// 定义UI详情数据接口
|
|
|
+interface DetailItemData {
|
|
|
+ name: string;
|
|
|
+ avatarPath: string;
|
|
|
+ characterId: number;
|
|
|
+}
|
|
|
+
|
|
|
+// 定义统计结果类型
|
|
|
+interface GameStats {
|
|
|
+ passedRealCount: number; // 放行的邻居数量
|
|
|
+ dismissedFakeCount: number; // 驱赶的伪人数量
|
|
|
+ passedFakeCount: number; // 放行的伪人数量
|
|
|
+ dismissedRealCount: number; // 驱赶的邻居数量
|
|
|
+ passedRealList: DetailItemData[]; // 放行的邻居列表
|
|
|
+ dismissedFakeList: DetailItemData[]; // 驱赶的伪人列表
|
|
|
+ passedFakeList: DetailItemData[]; // 放行的伪人列表
|
|
|
+ dismissedRealList: DetailItemData[]; // 驱赶的邻居列表
|
|
|
+ grade: string; // 评分:A/B/C/D
|
|
|
+}
|
|
|
+
|
|
|
+@ccclass('SummaryManager')
|
|
|
+export class SummaryManager extends Component {
|
|
|
+ @property({
|
|
|
+ type: Node,
|
|
|
+ tooltip: '总结面板节点'
|
|
|
+ })
|
|
|
+ summaryPanel: Node = null;
|
|
|
+
|
|
|
+ @property({
|
|
|
+ type: Label,
|
|
|
+ tooltip: '放行邻居数量文本'
|
|
|
+ })
|
|
|
+ passedRealCountLabel: Label = null;
|
|
|
+
|
|
|
+ @property({
|
|
|
+ type: Label,
|
|
|
+ tooltip: '驱赶伪人数量文本'
|
|
|
+ })
|
|
|
+ dismissedFakeCountLabel: Label = null;
|
|
|
+
|
|
|
+ @property({
|
|
|
+ type: Label,
|
|
|
+ tooltip: '放行伪人数量文本'
|
|
|
+ })
|
|
|
+ passedFakeCountLabel: Label = null;
|
|
|
+
|
|
|
+ @property({
|
|
|
+ type: Label,
|
|
|
+ tooltip: '驱赶邻居数量文本'
|
|
|
+ })
|
|
|
+ dismissedRealCountLabel: Label = null;
|
|
|
+
|
|
|
+ @property({
|
|
|
+ type: Label,
|
|
|
+ tooltip: '等级评分文本'
|
|
|
+ })
|
|
|
+ gradeLabel: Label = null;
|
|
|
+
|
|
|
+ @property({
|
|
|
+ type: Button,
|
|
|
+ tooltip: '查看放行伪人详情按钮'
|
|
|
+ })
|
|
|
+ viewPassedFakeButton: Button = null;
|
|
|
+
|
|
|
+ @property({
|
|
|
+ type: Button,
|
|
|
+ tooltip: '查看驱赶邻居详情按钮'
|
|
|
+ })
|
|
|
+ viewDismissedRealButton: Button = null;
|
|
|
+
|
|
|
+ @property({
|
|
|
+ type: Node,
|
|
|
+ tooltip: '详情面板节点'
|
|
|
+ })
|
|
|
+ detailPanel: Node = null;
|
|
|
+
|
|
|
+ @property({
|
|
|
+ type: Label,
|
|
|
+ tooltip: '详情面板标题'
|
|
|
+ })
|
|
|
+ detailTitleLabel: Label = null;
|
|
|
+
|
|
|
+ @property({
|
|
|
+ type: Node,
|
|
|
+ tooltip: '详情内容容器节点'
|
|
|
+ })
|
|
|
+ detailContentContainer: Node = null;
|
|
|
+
|
|
|
+ @property({
|
|
|
+ type: Node,
|
|
|
+ tooltip: '详情条目预制体'
|
|
|
+ })
|
|
|
+ detailItemPrefab: Node = null;
|
|
|
+
|
|
|
+ @property({
|
|
|
+ type: Button,
|
|
|
+ tooltip: '详情面板关闭按钮'
|
|
|
+ })
|
|
|
+ detailCloseButton: Button = null;
|
|
|
+
|
|
|
+ @property({
|
|
|
+ type: Node,
|
|
|
+ tooltip: '角色详情面板'
|
|
|
+ })
|
|
|
+ characterDetailPanel: Node = null;
|
|
|
+
|
|
|
+ @property({
|
|
|
+ type: DataManager,
|
|
|
+ tooltip: '数据管理器引用'
|
|
|
+ })
|
|
|
+ dataManager: DataManager = null;
|
|
|
+
|
|
|
+ @property({
|
|
|
+ type: Button,
|
|
|
+ tooltip: '确认按钮'
|
|
|
+ })
|
|
|
+ confirmButton: Button = null;
|
|
|
+
|
|
|
+ @property({
|
|
|
+ type: GameFlowManager,
|
|
|
+ tooltip: '游戏流程管理器引用'
|
|
|
+ })
|
|
|
+ gameFlowManager: GameFlowManager = null;
|
|
|
+
|
|
|
+ // 游戏统计数据
|
|
|
+ private gameStats: GameStats = {
|
|
|
+ passedRealCount: 0,
|
|
|
+ dismissedFakeCount: 0,
|
|
|
+ passedFakeCount: 0,
|
|
|
+ dismissedRealCount: 0,
|
|
|
+ passedRealList: [],
|
|
|
+ dismissedFakeList: [],
|
|
|
+ passedFakeList: [],
|
|
|
+ dismissedRealList: [],
|
|
|
+ grade: 'D'
|
|
|
+ };
|
|
|
+
|
|
|
+ // 当前显示的详情类型
|
|
|
+ private currentDetailType: 'passedFake' | 'dismissedReal' = null;
|
|
|
+
|
|
|
+ // 在SummaryManager中添加回调属性
|
|
|
+ public onShowCharacterDetail: (characterId: number) => void = null;
|
|
|
+
|
|
|
+ // 添加初始化标记
|
|
|
+ private isInitialized: boolean = false;
|
|
|
+
|
|
|
+ // 添加标记表示是否正在显示总结面板
|
|
|
+ private isShowingSummary: boolean = false;
|
|
|
+
|
|
|
+ start() {
|
|
|
+ console.log('SummaryManager.start被调用');
|
|
|
+
|
|
|
+ // 避免重复初始化
|
|
|
+ if (this.isInitialized) {
|
|
|
+ console.log('SummaryManager已经初始化过,跳过初始化流程');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果正在显示总结面板,跳过隐藏面板的步骤
|
|
|
+ if (this.isShowingSummary) {
|
|
|
+ console.log('总结面板正在显示中,跳过隐藏面板的初始化步骤');
|
|
|
+ this.isInitialized = true;
|
|
|
+ this.setupButtons();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查面板引用
|
|
|
+ if (!this.summaryPanel) {
|
|
|
+ console.error('summaryPanel未被赋值,请检查Inspector中的引用设置');
|
|
|
+ } else {
|
|
|
+ console.log('summaryPanel初始状态:', this.summaryPanel.active);
|
|
|
+ // 初始化隐藏面板,但先记录下它的初始状态以便调试
|
|
|
+ this.summaryPanel.active = false;
|
|
|
+ console.log('summaryPanel已设置为隐藏');
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!this.detailPanel) {
|
|
|
+ console.error('detailPanel未被赋值,请检查Inspector中的引用设置');
|
|
|
+ } else {
|
|
|
+ console.log('detailPanel初始状态:', this.detailPanel.active);
|
|
|
+ this.detailPanel.active = false;
|
|
|
+ console.log('detailPanel已设置为隐藏');
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!this.characterDetailPanel) {
|
|
|
+ console.error('characterDetailPanel未被赋值,请检查Inspector中的引用设置');
|
|
|
+ } else {
|
|
|
+ console.log('characterDetailPanel初始状态:', this.characterDetailPanel.active);
|
|
|
+ this.characterDetailPanel.active = false;
|
|
|
+ console.log('characterDetailPanel已设置为隐藏');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 注册按钮事件
|
|
|
+ this.setupButtons();
|
|
|
+
|
|
|
+ // 标记为已初始化
|
|
|
+ this.isInitialized = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置按钮事件
|
|
|
+ */
|
|
|
+ private setupButtons(): void {
|
|
|
+ // 查看放行伪人详情按钮
|
|
|
+ if (this.viewPassedFakeButton) {
|
|
|
+ this.viewPassedFakeButton.node.on(Button.EventType.CLICK, () => {
|
|
|
+ this.showDetailPanel('passedFake');
|
|
|
+ }, this);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查看驱赶邻居详情按钮
|
|
|
+ if (this.viewDismissedRealButton) {
|
|
|
+ this.viewDismissedRealButton.node.on(Button.EventType.CLICK, () => {
|
|
|
+ this.showDetailPanel('dismissedReal');
|
|
|
+ }, this);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 详情面板关闭按钮
|
|
|
+ if (this.detailCloseButton) {
|
|
|
+ this.detailCloseButton.node.on(Button.EventType.CLICK, () => {
|
|
|
+ this.hideDetailPanel();
|
|
|
+ }, this);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 确认按钮
|
|
|
+ if (this.confirmButton) {
|
|
|
+ this.confirmButton.node.on(Button.EventType.CLICK, this.handleConfirmButtonClick, this);
|
|
|
+ } else {
|
|
|
+ console.error('确认按钮未设置');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 记录放行NPC
|
|
|
+ * @param npcData NPC数据
|
|
|
+ */
|
|
|
+ public recordPassedNPC(npcData: any): void {
|
|
|
+ if (!npcData) return;
|
|
|
+
|
|
|
+ console.log(`记录放行NPC: ${npcData.characterName}, 类型: ${npcData.type}, ID: ${npcData.characterId}`);
|
|
|
+
|
|
|
+ const detailData: DetailItemData = {
|
|
|
+ name: npcData.characterName,
|
|
|
+ avatarPath: `avatars/${npcData.characterId}/avatar_${npcData.characterId}_5`,
|
|
|
+ characterId: npcData.characterId
|
|
|
+ };
|
|
|
+
|
|
|
+ if (npcData.type === 'real') {
|
|
|
+ // 放行了邻居
|
|
|
+ this.gameStats.passedRealCount++;
|
|
|
+ this.gameStats.passedRealList.push(detailData);
|
|
|
+ console.log(`放行邻居数量增加到 ${this.gameStats.passedRealCount}`);
|
|
|
+ } else if (npcData.type === 'fake') {
|
|
|
+ // 放行了伪人
|
|
|
+ this.gameStats.passedFakeCount++;
|
|
|
+ this.gameStats.passedFakeList.push(detailData);
|
|
|
+ console.log(`放行伪人数量增加到 ${this.gameStats.passedFakeCount}`);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新评分
|
|
|
+ this.updateGrade();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 记录驱赶NPC
|
|
|
+ * @param npcData NPC数据
|
|
|
+ */
|
|
|
+ public recordDismissedNPC(npcData: any): void {
|
|
|
+ if (!npcData) return;
|
|
|
+
|
|
|
+ console.log(`记录驱赶NPC: ${npcData.characterName}, 类型: ${npcData.type}, ID: ${npcData.characterId}`);
|
|
|
+
|
|
|
+ const detailData: DetailItemData = {
|
|
|
+ name: npcData.characterName,
|
|
|
+ avatarPath: `avatars/${npcData.characterId}/avatar_${npcData.characterId}_5`,
|
|
|
+ characterId: npcData.characterId
|
|
|
+ };
|
|
|
+
|
|
|
+ if (npcData.type === 'real') {
|
|
|
+ // 驱赶了邻居
|
|
|
+ this.gameStats.dismissedRealCount++;
|
|
|
+ this.gameStats.dismissedRealList.push(detailData);
|
|
|
+ console.log(`驱赶邻居数量增加到 ${this.gameStats.dismissedRealCount}`);
|
|
|
+ } else if (npcData.type === 'fake') {
|
|
|
+ // 驱赶了伪人
|
|
|
+ this.gameStats.dismissedFakeCount++;
|
|
|
+ this.gameStats.dismissedFakeList.push(detailData);
|
|
|
+ console.log(`驱赶伪人数量增加到 ${this.gameStats.dismissedFakeCount}`);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新评分
|
|
|
+ this.updateGrade();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新评分
|
|
|
+ */
|
|
|
+ private updateGrade(): void {
|
|
|
+ // 计算正确决策的百分比
|
|
|
+ const totalDecisions = this.gameStats.passedRealCount + this.gameStats.dismissedFakeCount +
|
|
|
+ this.gameStats.passedFakeCount + this.gameStats.dismissedRealCount;
|
|
|
+
|
|
|
+ if (totalDecisions === 0) {
|
|
|
+ this.gameStats.grade = 'D';
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const correctDecisions = this.gameStats.passedRealCount + this.gameStats.dismissedFakeCount;
|
|
|
+ const correctPercentage = (correctDecisions / totalDecisions) * 100;
|
|
|
+
|
|
|
+ // 根据正确率确定等级
|
|
|
+ if (correctPercentage >= 90) {
|
|
|
+ this.gameStats.grade = 'A';
|
|
|
+ } else if (correctPercentage >= 70) {
|
|
|
+ this.gameStats.grade = 'B';
|
|
|
+ } else if (correctPercentage >= 50) {
|
|
|
+ this.gameStats.grade = 'C';
|
|
|
+ } else {
|
|
|
+ this.gameStats.grade = 'D';
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 显示总结面板
|
|
|
+ */
|
|
|
+ public showSummaryPanel(): void {
|
|
|
+ console.log('SummaryManager.showSummaryPanel被调用');
|
|
|
+
|
|
|
+ // 尝试检查资源路径
|
|
|
+ this.checkAvatarResources();
|
|
|
+
|
|
|
+ // 标记为正在显示总结面板
|
|
|
+ this.isShowingSummary = true;
|
|
|
+
|
|
|
+ // 确保已初始化
|
|
|
+ if (!this.isInitialized) {
|
|
|
+ console.log('SummaryManager未初始化,执行初始化');
|
|
|
+ this.isInitialized = true; // 标记为已初始化,避免start中再次隐藏面板
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!this.summaryPanel) {
|
|
|
+ console.error('summaryPanel未设置');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查summaryPanel的父节点状态
|
|
|
+ const parentNode = this.summaryPanel.parent;
|
|
|
+ if (parentNode) {
|
|
|
+ console.log('summaryPanel父节点状态:', parentNode.name, '激活状态:', parentNode.active);
|
|
|
+ // 确保父节点也是激活的
|
|
|
+ if (!parentNode.active) {
|
|
|
+ console.log('激活summaryPanel的父节点');
|
|
|
+ parentNode.active = true;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ console.error('summaryPanel没有父节点');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 强制设置可见性相关属性
|
|
|
+ this.summaryPanel.active = true;
|
|
|
+
|
|
|
+ // 确保位于最顶层
|
|
|
+ this.summaryPanel.setSiblingIndex(999);
|
|
|
+
|
|
|
+ // 尝试强制将面板移动到场景顶层
|
|
|
+ this.forceMoveToTop();
|
|
|
+
|
|
|
+ // 如果节点有UIOpacity组件,确保不透明
|
|
|
+ const opacityComp = this.summaryPanel.getComponent(UIOpacity);
|
|
|
+ if (opacityComp) {
|
|
|
+ console.log('设置summaryPanel的不透明度为255');
|
|
|
+ opacityComp.opacity = 255;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果有widget组件,可能需要更新对齐
|
|
|
+ const widgetComp = this.summaryPanel.getComponent(Widget);
|
|
|
+ if (widgetComp) {
|
|
|
+ console.log('更新summaryPanel的Widget对齐');
|
|
|
+ widgetComp.updateAlignment();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查summaryPanel的位置和大小
|
|
|
+ console.log('summaryPanel位置:', this.summaryPanel.position);
|
|
|
+ const uiTransform = this.summaryPanel.getComponent(UITransform);
|
|
|
+ if (uiTransform) {
|
|
|
+ console.log('summaryPanel大小:', uiTransform.contentSize);
|
|
|
+ } else {
|
|
|
+ console.log('summaryPanel没有UITransform组件');
|
|
|
+ }
|
|
|
+ console.log('summaryPanel缩放:', this.summaryPanel.scale);
|
|
|
+ console.log('summaryPanel角度:', this.summaryPanel.angle);
|
|
|
+ console.log('summaryPanel激活状态:', this.summaryPanel.active);
|
|
|
+
|
|
|
+ // 检查summaryPanel的子节点状态
|
|
|
+ const children = this.summaryPanel.children;
|
|
|
+ console.log(`summaryPanel有 ${children.length} 个子节点`);
|
|
|
+ children.forEach((child, index) => {
|
|
|
+ console.log(`子节点 ${index}: ${child.name}, 激活状态: ${child.active}`);
|
|
|
+ });
|
|
|
+
|
|
|
+ // 更新UI显示
|
|
|
+ this.updateSummaryUI();
|
|
|
+
|
|
|
+ console.log('成功激活summaryPanel,位置:', this.summaryPanel.position);
|
|
|
+
|
|
|
+ // 添加延迟操作,确保UI正确显示
|
|
|
+ this.scheduleOnce(() => {
|
|
|
+ console.log('延迟处理:再次确认summaryPanel是否显示');
|
|
|
+ if (this.summaryPanel) {
|
|
|
+ if (!this.summaryPanel.active) {
|
|
|
+ console.log('延迟处理:summaryPanel未激活,尝试再次激活');
|
|
|
+ this.summaryPanel.active = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 再次确保位于最顶层
|
|
|
+ this.summaryPanel.setSiblingIndex(999);
|
|
|
+
|
|
|
+ // 再次强制更新UI显示
|
|
|
+ this.updateSummaryUI();
|
|
|
+
|
|
|
+ console.log('延迟处理:summaryPanel状态:', this.summaryPanel.active);
|
|
|
+ }
|
|
|
+ }, 0.1); // 延迟0.1秒
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 强制将总结面板移动到场景最顶层
|
|
|
+ */
|
|
|
+ private forceMoveToTop(): void {
|
|
|
+ console.log('尝试强制将总结面板移动到最顶层');
|
|
|
+
|
|
|
+ // 查找当前场景的Canvas
|
|
|
+ const scene = director.getScene();
|
|
|
+ if (!scene) {
|
|
|
+ console.error('无法获取当前场景');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log('当前场景:', scene.name);
|
|
|
+
|
|
|
+ // 遍历场景节点查找Canvas
|
|
|
+ let canvasNode = null;
|
|
|
+ const findCanvas = (node: Node) => {
|
|
|
+ if (node.getComponent(Canvas)) {
|
|
|
+ canvasNode = node;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (let i = 0; i < node.children.length; i++) {
|
|
|
+ if (findCanvas(node.children[i])) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+ };
|
|
|
+
|
|
|
+ findCanvas(scene);
|
|
|
+
|
|
|
+ if (canvasNode) {
|
|
|
+ console.log('找到Canvas节点:', canvasNode.name);
|
|
|
+
|
|
|
+ // 如果summaryPanel不在Canvas下,尝试将其移动到Canvas
|
|
|
+ if (this.summaryPanel.parent !== canvasNode) {
|
|
|
+ console.log('summaryPanel不在Canvas下,尝试移动');
|
|
|
+
|
|
|
+ // 保存原始父节点以便恢复
|
|
|
+ const originalParent = this.summaryPanel.parent;
|
|
|
+
|
|
|
+ // 记录当前位置
|
|
|
+ const originalPosition = this.summaryPanel.position.clone();
|
|
|
+
|
|
|
+ // 尝试将面板添加到Canvas
|
|
|
+ this.summaryPanel.parent = canvasNode;
|
|
|
+ this.summaryPanel.setSiblingIndex(canvasNode.children.length - 1);
|
|
|
+
|
|
|
+ console.log('summaryPanel已移动到Canvas下,索引:', this.summaryPanel.getSiblingIndex());
|
|
|
+ } else {
|
|
|
+ console.log('summaryPanel已在Canvas下,设置最高索引');
|
|
|
+ this.summaryPanel.setSiblingIndex(canvasNode.children.length - 1);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ console.error('场景中未找到Canvas节点');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 隐藏总结面板
|
|
|
+ */
|
|
|
+ public hideSummaryPanel(): void {
|
|
|
+ console.log('SummaryManager.hideSummaryPanel被调用');
|
|
|
+
|
|
|
+ // 更新显示标志
|
|
|
+ this.isShowingSummary = false;
|
|
|
+
|
|
|
+ if (this.summaryPanel) {
|
|
|
+ this.summaryPanel.active = false;
|
|
|
+ console.log('总结面板已隐藏');
|
|
|
+ } else {
|
|
|
+ console.error('summaryPanel未设置,无法隐藏');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新总结UI显示
|
|
|
+ */
|
|
|
+ private updateSummaryUI(): void {
|
|
|
+ console.log('updateSummaryUI被调用,准备更新UI显示');
|
|
|
+
|
|
|
+ // 检查标签引用是否存在
|
|
|
+ if (!this.passedRealCountLabel) {
|
|
|
+ console.error('passedRealCountLabel未设置');
|
|
|
+ } else {
|
|
|
+ console.log(`设置放行邻居数量: ${this.gameStats.passedRealCount}`);
|
|
|
+ this.passedRealCountLabel.string = String(this.gameStats.passedRealCount);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!this.dismissedFakeCountLabel) {
|
|
|
+ console.error('dismissedFakeCountLabel未设置');
|
|
|
+ } else {
|
|
|
+ console.log(`设置驱赶伪人数量: ${this.gameStats.dismissedFakeCount}`);
|
|
|
+ this.dismissedFakeCountLabel.string = String(this.gameStats.dismissedFakeCount);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!this.passedFakeCountLabel) {
|
|
|
+ console.error('passedFakeCountLabel未设置');
|
|
|
+ } else {
|
|
|
+ console.log(`设置放行伪人数量: ${this.gameStats.passedFakeCount}`);
|
|
|
+ this.passedFakeCountLabel.string = String(this.gameStats.passedFakeCount);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!this.dismissedRealCountLabel) {
|
|
|
+ console.error('dismissedRealCountLabel未设置');
|
|
|
+ } else {
|
|
|
+ console.log(`设置驱赶邻居数量: ${this.gameStats.dismissedRealCount}`);
|
|
|
+ this.dismissedRealCountLabel.string = String(this.gameStats.dismissedRealCount);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新等级评分
|
|
|
+ if (!this.gradeLabel) {
|
|
|
+ console.error('gradeLabel未设置');
|
|
|
+ } else {
|
|
|
+ console.log(`设置评分等级: ${this.gameStats.grade}`);
|
|
|
+ this.gradeLabel.string = this.gameStats.grade;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查按钮状态
|
|
|
+ console.log(`放行伪人列表数量: ${this.gameStats.passedFakeList.length}`);
|
|
|
+ if (this.viewPassedFakeButton) {
|
|
|
+ // 根据列表是否有内容来启用/禁用按钮
|
|
|
+ this.viewPassedFakeButton.interactable = this.gameStats.passedFakeList.length > 0;
|
|
|
+ console.log(`设置放行伪人详情按钮状态: ${this.viewPassedFakeButton.interactable}`);
|
|
|
+ } else {
|
|
|
+ console.error('viewPassedFakeButton未设置');
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log(`驱赶邻居列表数量: ${this.gameStats.dismissedRealList.length}`);
|
|
|
+ if (this.viewDismissedRealButton) {
|
|
|
+ // 根据列表是否有内容来启用/禁用按钮
|
|
|
+ this.viewDismissedRealButton.interactable = this.gameStats.dismissedRealList.length > 0;
|
|
|
+ console.log(`设置驱赶邻居详情按钮状态: ${this.viewDismissedRealButton.interactable}`);
|
|
|
+ } else {
|
|
|
+ console.error('viewDismissedRealButton未设置');
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log('UI显示更新完成');
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 显示详情面板
|
|
|
+ * @param detailType 详情类型
|
|
|
+ */
|
|
|
+ private showDetailPanel(detailType: 'passedFake' | 'dismissedReal'): void {
|
|
|
+ if (!this.detailPanel || !this.detailContentContainer) return;
|
|
|
+
|
|
|
+ this.currentDetailType = detailType;
|
|
|
+
|
|
|
+ // 设置标题
|
|
|
+ if (this.detailTitleLabel) {
|
|
|
+ this.detailTitleLabel.string = detailType === 'passedFake' ? '放进来的伪人' : '驱赶的邻居';
|
|
|
+ }
|
|
|
+
|
|
|
+ // 清空容器
|
|
|
+ this.detailContentContainer.removeAllChildren();
|
|
|
+
|
|
|
+ // 获取详情列表
|
|
|
+ const detailList = detailType === 'passedFake' ?
|
|
|
+ this.gameStats.passedFakeList : this.gameStats.dismissedRealList;
|
|
|
+
|
|
|
+ // 创建详情条目
|
|
|
+ detailList.forEach(detail => {
|
|
|
+ this.createDetailItem(detail);
|
|
|
+ });
|
|
|
+
|
|
|
+ // 显示面板
|
|
|
+ this.detailPanel.active = true;
|
|
|
+ this.detailPanel.setSiblingIndex(1000); // 确保显示在总结面板之上
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 隐藏详情面板
|
|
|
+ */
|
|
|
+ private hideDetailPanel(): void {
|
|
|
+ if (this.detailPanel) {
|
|
|
+ this.detailPanel.active = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建详情条目
|
|
|
+ * @param detailData 详情数据
|
|
|
+ */
|
|
|
+ private createDetailItem(detailData: DetailItemData): void {
|
|
|
+ if (!this.detailItemPrefab || !this.detailContentContainer) return;
|
|
|
+
|
|
|
+ console.log(`创建详情条目: ${detailData.name}, 头像路径: ${detailData.avatarPath}, 类型: ${this.currentDetailType}`);
|
|
|
+
|
|
|
+ // 实例化预制体
|
|
|
+ const itemNode = instantiate(this.detailItemPrefab);
|
|
|
+ this.detailContentContainer.addChild(itemNode);
|
|
|
+
|
|
|
+ // 设置名称
|
|
|
+ const nameLabel = itemNode.getChildByName('Name')?.getComponent(Label);
|
|
|
+ if (nameLabel) {
|
|
|
+ nameLabel.string = detailData.name;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置头像
|
|
|
+ const avatarSprite = itemNode.getChildByName('Avatar')?.getComponent(Sprite);
|
|
|
+ if (avatarSprite) {
|
|
|
+ // 列出所有可能尝试的路径格式
|
|
|
+ let pathsToTry = [];
|
|
|
+
|
|
|
+ if (this.currentDetailType === 'passedFake') {
|
|
|
+ // 如果是"放行的伪人",使用黑影图片
|
|
|
+ console.log('加载黑影头像');
|
|
|
+ pathsToTry = [
|
|
|
+ 'avatars/black/spriteFrame',
|
|
|
+ 'avatars/black',
|
|
|
+ 'avatars/黑影/spriteFrame',
|
|
|
+ 'avatars/黑影',
|
|
|
+ 'black/spriteFrame',
|
|
|
+ 'black',
|
|
|
+ '黑影/spriteFrame',
|
|
|
+ '黑影'
|
|
|
+ ];
|
|
|
+ } else {
|
|
|
+ // 如果是"驱赶的邻居"或其他,正常加载头像
|
|
|
+ console.log(`加载角色头像: ${detailData.avatarPath}`);
|
|
|
+ const baseAvatarPath = detailData.avatarPath;
|
|
|
+ pathsToTry = [
|
|
|
+ `${baseAvatarPath}/spriteFrame`,
|
|
|
+ baseAvatarPath,
|
|
|
+ `avatars/${detailData.characterId}/avatar_${detailData.characterId}_5/spriteFrame`,
|
|
|
+ `avatars/${detailData.characterId}/avatar_${detailData.characterId}_5`,
|
|
|
+ `avatars/${detailData.characterId}/spriteFrame`,
|
|
|
+ `avatars/${detailData.characterId}`
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 递归尝试加载所有可能的路径
|
|
|
+ this.tryLoadSpriteFrameWithPaths(avatarSprite, pathsToTry, 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置查看详情按钮事件
|
|
|
+ const detailButton = itemNode.getChildByName('DetailButton')?.getComponent(Button);
|
|
|
+ if (detailButton) {
|
|
|
+ detailButton.node.on(Button.EventType.CLICK, () => {
|
|
|
+ this.showCharacterDetail(detailData.characterId);
|
|
|
+ }, this);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 递归尝试加载所有可能的路径
|
|
|
+ * @param sprite 要设置的精灵组件
|
|
|
+ * @param paths 尝试的路径数组
|
|
|
+ * @param index 当前尝试的路径索引
|
|
|
+ */
|
|
|
+ private tryLoadSpriteFrameWithPaths(sprite: Sprite, paths: string[], index: number): void {
|
|
|
+ if (index >= paths.length) {
|
|
|
+ console.error('所有可能的路径都尝试失败,使用默认图像');
|
|
|
+ // 所有路径都失败,创建一个默认的灰色方形作为备用
|
|
|
+ this.createDefaultSpriteFrame(sprite);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const currentPath = paths[index];
|
|
|
+ console.log(`尝试加载路径(${index+1}/${paths.length}): ${currentPath}`);
|
|
|
+
|
|
|
+ resources.load(currentPath, SpriteFrame, (err, spriteFrame) => {
|
|
|
+ if (err) {
|
|
|
+ console.warn(`路径加载失败: ${currentPath}`, err);
|
|
|
+ // 尝试下一个路径
|
|
|
+ this.tryLoadSpriteFrameWithPaths(sprite, paths, index + 1);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 成功加载,设置spriteFrame
|
|
|
+ sprite.spriteFrame = spriteFrame;
|
|
|
+ console.log(`成功加载头像: ${currentPath}`);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建一个默认的SpriteFrame用于显示
|
|
|
+ * @param sprite 要设置的精灵组件
|
|
|
+ */
|
|
|
+ private createDefaultSpriteFrame(sprite: Sprite): void {
|
|
|
+ console.log('创建默认图像');
|
|
|
+
|
|
|
+ // 使用内置资源或默认资源
|
|
|
+ const defaultIcon = "default_sprite";
|
|
|
+ resources.load(defaultIcon, SpriteFrame, (err, spriteFrame) => {
|
|
|
+ if (err) {
|
|
|
+ console.warn(`无法加载默认图像 ${defaultIcon}`, err);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ sprite.spriteFrame = spriteFrame;
|
|
|
+ console.log('已设置默认图像');
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 显示角色详情
|
|
|
+ * @param characterId 角色ID
|
|
|
+ */
|
|
|
+ private showCharacterDetail(characterId: number): void {
|
|
|
+ if (!this.characterDetailPanel) return;
|
|
|
+
|
|
|
+ console.log(`显示角色详情: ID=${characterId}`);
|
|
|
+
|
|
|
+ // 获取角色数据
|
|
|
+ const npcData = this.dataManager.getNPCById(characterId);
|
|
|
+ if (!npcData) {
|
|
|
+ console.error(`无法找到ID为${characterId}的NPC数据`);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log(`找到NPC数据: ${npcData.characterName}`);
|
|
|
+
|
|
|
+ // 通过事件系统通知GameFlow处理
|
|
|
+ // 或者提供一个回调函数由GameFlow注入
|
|
|
+ if (this.onShowCharacterDetail) {
|
|
|
+ console.log(`调用onShowCharacterDetail回调函数显示角色详情`);
|
|
|
+ this.onShowCharacterDetail(characterId);
|
|
|
+ } else {
|
|
|
+ console.error(`onShowCharacterDetail回调未设置,无法显示角色详情`);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 重置统计数据
|
|
|
+ */
|
|
|
+ public resetStats(): void {
|
|
|
+ console.log('SummaryManager.resetStats被调用,重置统计数据');
|
|
|
+
|
|
|
+ this.gameStats = {
|
|
|
+ passedRealCount: 0,
|
|
|
+ dismissedFakeCount: 0,
|
|
|
+ passedFakeCount: 0,
|
|
|
+ dismissedRealCount: 0,
|
|
|
+ passedRealList: [],
|
|
|
+ dismissedFakeList: [],
|
|
|
+ passedFakeList: [],
|
|
|
+ dismissedRealList: [],
|
|
|
+ grade: 'D'
|
|
|
+ };
|
|
|
+
|
|
|
+ // 重置显示标志,但不要隐藏面板
|
|
|
+ this.isShowingSummary = false;
|
|
|
+
|
|
|
+ console.log('统计数据已重置');
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理确认按钮点击
|
|
|
+ */
|
|
|
+ private handleConfirmButtonClick(): void {
|
|
|
+ console.log('确认按钮被点击,准备切换到下一关');
|
|
|
+
|
|
|
+ // 隐藏当前面板
|
|
|
+ this.hideSummaryPanel();
|
|
|
+
|
|
|
+ // 检查游戏流程管理器是否存在
|
|
|
+ if (!this.gameFlowManager) {
|
|
|
+ console.error('游戏流程管理器未设置,无法切换到下一关');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 使用DataManager切换到下一关
|
|
|
+ if (this.dataManager) {
|
|
|
+ // 先重置统计数据
|
|
|
+ this.resetStats();
|
|
|
+
|
|
|
+ // 切换到下一关
|
|
|
+ const hasNextLevel = this.dataManager.nextLevel();
|
|
|
+
|
|
|
+ if (hasNextLevel) {
|
|
|
+ console.log('成功切换到下一关,准备开始新关卡');
|
|
|
+
|
|
|
+ // 重新开始游戏流程
|
|
|
+ this.gameFlowManager.restartGameFlow();
|
|
|
+ } else {
|
|
|
+ console.log('已经是最后一关,游戏结束');
|
|
|
+ // 这里可以添加游戏结束的处理逻辑
|
|
|
+ // 例如显示通关画面等
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ console.error('DataManager未设置,无法切换关卡');
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ onEnable() {
|
|
|
+ console.log('SummaryManager.onEnable被调用');
|
|
|
+
|
|
|
+ // 如果正在显示总结面板,确保面板保持显示状态
|
|
|
+ if (this.isShowingSummary && this.summaryPanel) {
|
|
|
+ console.log('onEnable: 总结面板正在显示中,确保保持显示状态');
|
|
|
+ this.summaryPanel.active = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ onDestroy() {
|
|
|
+ // 清理按钮事件
|
|
|
+ if (this.viewPassedFakeButton) {
|
|
|
+ this.viewPassedFakeButton.node.off(Button.EventType.CLICK);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.viewDismissedRealButton) {
|
|
|
+ this.viewDismissedRealButton.node.off(Button.EventType.CLICK);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.detailCloseButton) {
|
|
|
+ this.detailCloseButton.node.off(Button.EventType.CLICK);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.confirmButton) {
|
|
|
+ this.confirmButton.node.off(Button.EventType.CLICK, this.handleConfirmButtonClick, this);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查头像资源目录结构
|
|
|
+ */
|
|
|
+ private checkAvatarResources(): void {
|
|
|
+ console.log('检查avatars资源目录结构...');
|
|
|
+
|
|
|
+ // 检查black图片是否存在
|
|
|
+ resources.load('avatars/black/spriteFrame', SpriteFrame, (err, asset) => {
|
|
|
+ if (err) {
|
|
|
+ console.error('avatars/black不存在', err);
|
|
|
+ } else {
|
|
|
+ console.log('成功加载avatars/black');
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 尝试列出avatars目录下的内容
|
|
|
+ resources.loadDir('avatars', (err, assets) => {
|
|
|
+ if (err) {
|
|
|
+ console.error('无法加载avatars目录', err);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log(`avatars目录中有 ${assets.length} 个资源:`);
|
|
|
+ assets.forEach((asset, index) => {
|
|
|
+ console.log(`${index + 1}. ${asset.name} (类型: ${typeof asset})`);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+}
|