/** * GameEnd节点实际状态调试脚本 * 模拟实际游戏环境,检查GameEnd节点的各种状态 */ // 模拟事件系统 class MockEventBus { constructor() { this.listeners = new Map(); this.eventLog = []; } on(event, callback, context) { if (!this.listeners.has(event)) { this.listeners.set(event, []); } this.listeners.get(event).push({ callback, context }); console.log(`[EventBus] 注册事件监听器: ${event}`); } emit(event, ...args) { console.log(`[EventBus] 触发事件: ${event}`); this.eventLog.push({ event, timestamp: Date.now(), args }); if (this.listeners.has(event)) { const listeners = this.listeners.get(event); listeners.forEach(({ callback, context }) => { try { callback.call(context, ...args); } catch (error) { console.error(`[EventBus] 事件处理错误 ${event}:`, error); } }); } } off(event, callback, context) { if (this.listeners.has(event)) { const listeners = this.listeners.get(event); const index = listeners.findIndex(l => l.callback === callback && l.context === context); if (index !== -1) { listeners.splice(index, 1); console.log(`[EventBus] 移除事件监听器: ${event}`); } } } getEventLog() { return this.eventLog; } } // 模拟GameEvents const GameEvents = { GAME_DEFEAT: 'GAME_DEFEAT', GAME_RESUME: 'GAME_RESUME', GAME_START: 'GAME_START', RESET_UI_STATES: 'RESET_UI_STATES' }; // 模拟UIOpacity组件 class MockUIOpacity { constructor() { this.opacity = 255; } } // 模拟Node class MockNode { constructor(name, parent = null) { this.name = name; this.active = true; this.scale = { x: 1, y: 1, z: 1 }; this.position = { x: 0, y: 0, z: 0 }; this.parent = parent; this.children = []; this.components = new Map(); this.siblingIndex = 0; if (parent) { parent.children.push(this); this.siblingIndex = parent.children.length - 1; } } setScale(x, y, z) { this.scale = { x, y, z }; } setPosition(x, y, z) { this.position = { x, y, z }; } getComponent(componentType) { return this.components.get(componentType) || null; } addComponent(componentType) { const component = new componentType(); this.components.set(componentType, component); return component; } setSiblingIndex(index) { if (!this.parent) return; // 从当前位置移除 const currentIndex = this.parent.children.indexOf(this); if (currentIndex !== -1) { this.parent.children.splice(currentIndex, 1); } // 插入到新位置 this.parent.children.splice(index, 0, this); this.siblingIndex = index; // 更新其他子节点的siblingIndex this.parent.children.forEach((child, i) => { child.siblingIndex = i; }); } getNodeStatus() { return { name: this.name, active: this.active, scale: { ...this.scale }, position: { ...this.position }, siblingIndex: this.siblingIndex, opacity: this.getComponent(MockUIOpacity)?.opacity || 'N/A', childrenCount: this.children.length }; } } // 模拟Canvas层级结构 function createMockCanvasStructure() { const canvas = new MockNode('Canvas'); // 创建主要UI面板 const gameLevelUI = new MockNode('GameLevelUI', canvas); const topArea = new MockNode('TopArea', canvas); const gameEnd = new MockNode('GameEnd', canvas); const pauseMenu = new MockNode('PauseMenu', canvas); const settingsPanel = new MockNode('SettingsPanel', canvas); // 设置初始层级顺序(siblingIndex越大越在上层) gameLevelUI.setSiblingIndex(0); // 最底层 topArea.setSiblingIndex(1); gameEnd.setSiblingIndex(2); // GameEnd在中间层 pauseMenu.setSiblingIndex(3); settingsPanel.setSiblingIndex(4); // 最顶层 // 为GameEnd添加UIOpacity组件 gameEnd.addComponent(MockUIOpacity); console.log('[Canvas] 模拟Canvas层级结构创建完成'); console.log('[Canvas] 节点层级顺序(从底到顶):'); canvas.children.forEach((child, index) => { console.log(` ${index}: ${child.name} (siblingIndex: ${child.siblingIndex})`); }); return { canvas, gameEnd, pauseMenu, settingsPanel }; } // 模拟GameEnd组件(简化版) class MockGameEnd { constructor(node, eventBus) { this.node = node; this.eventBus = eventBus; this.animationDuration = 0.3; this.isVisible = false; this.animationCount = 0; this.hasProcessedGameEnd = false; this.setupEventListeners(); this.initializeHiddenStateKeepActive(); } setupEventListeners() { this.eventBus.on(GameEvents.GAME_DEFEAT, this.onGameDefeat, this); this.eventBus.on(GameEvents.RESET_UI_STATES, this.onResetUI, this); } onGameDefeat() { console.log('[GameEnd] 接收到GAME_DEFEAT事件'); console.log('[GameEnd] 游戏失败事件处理,开始统一处理流程'); if (this.hasProcessedGameEnd) { console.log('[GameEnd] 游戏结束已处理过,跳过重复计算'); return; } this.hasProcessedGameEnd = true; this.showEndPanelWithAnimation(); } showEndPanelWithAnimation() { console.log('[GameEnd] 开始显示结算面板动画'); // 检查节点状态 console.log('[GameEnd] 动画前节点状态:', this.node.getNodeStatus()); // 确保节点处于激活状态 if (!this.node.active) { this.node.active = true; console.log('[GameEnd] 激活GameEnd节点'); } // 检查是否被其他面板遮挡 this.checkUILayering(); // 确保有UIOpacity组件 let uiOpacity = this.node.getComponent(MockUIOpacity); if (!uiOpacity) { uiOpacity = this.node.addComponent(MockUIOpacity); console.log('[GameEnd] 添加UIOpacity组件'); } // 播放动画 if (this.animationDuration > 0) { console.log(`[GameEnd] 动画持续时间: ${this.animationDuration}秒,开始播放GameEnd面板弹出动画`); this.playShowAnimation(); } else { this.node.setScale(1, 1, 1); uiOpacity.opacity = 255; console.log('[GameEnd] 无动画配置,直接显示面板'); } this.animationCount++; this.isVisible = true; console.log('[GameEnd] 动画后节点状态:', this.node.getNodeStatus()); console.log('[GameEnd] GameEnd面板显示流程完成'); } playShowAnimation() { console.log('[GameEnd] 开始播放GameEnd面板弹出动画'); // 设置节点位置到屏幕中心 this.node.setPosition(0, 0, 0); console.log('[GameEnd] 已将面板居中到屏幕中央'); // 设置初始状态 this.node.setScale(0.3, 0.3, 1); const uiOpacity = this.node.getComponent(MockUIOpacity); if (uiOpacity) { uiOpacity.opacity = 0; } console.log('[GameEnd] 设置动画初始状态 - 缩放: 0.3, 透明度: 0'); // 模拟动画完成 setTimeout(() => { this.node.setScale(1, 1, 1); if (uiOpacity) { uiOpacity.opacity = 255; } console.log('[GameEnd] GameEnd面板缩放动画完成'); console.log('[GameEnd] GameEnd面板淡入动画完成'); }, this.animationDuration * 1000); console.log('[GameEnd] GameEnd面板弹出动画开始执行'); } initializeHiddenStateKeepActive() { const uiOpacity = this.node.getComponent(MockUIOpacity) || this.node.addComponent(MockUIOpacity); uiOpacity.opacity = 0; this.node.setScale(0.3, 0.3, 1); console.log('[GameEnd] 初始化为隐藏状态(保持激活) - 缩放: 0.3, 透明度: 0'); } onResetUI() { console.log('[GameEnd] 重置UI状态'); this.hasProcessedGameEnd = false; this.isVisible = false; this.node.active = false; console.log('[GameEnd] UI状态重置完成'); } checkUILayering() { if (!this.node.parent) return; console.log('[GameEnd] 检查UI层级:'); console.log(`[GameEnd] 当前GameEnd的siblingIndex: ${this.node.siblingIndex}`); // 检查是否有其他激活的UI面板在更高层级 const higherLevelPanels = this.node.parent.children.filter(child => child.siblingIndex > this.node.siblingIndex && child.active && child !== this.node ); if (higherLevelPanels.length > 0) { console.log('[GameEnd] ⚠️ 发现更高层级的激活面板:'); higherLevelPanels.forEach(panel => { console.log(`[GameEnd] - ${panel.name} (siblingIndex: ${panel.siblingIndex})`); }); console.log('[GameEnd] 这些面板可能遮挡GameEnd显示'); } else { console.log('[GameEnd] ✅ 没有更高层级的面板遮挡'); } } getStatus() { return { animationCount: this.animationCount, isVisible: this.isVisible, hasProcessedGameEnd: this.hasProcessedGameEnd, nodeStatus: this.node.getNodeStatus() }; } } // 模拟Wall组件 class MockWall { constructor(eventBus) { this.eventBus = eventBus; this.currentHealth = 100; this.maxHealth = 100; } takeDamage(damage) { console.log(`[Wall] 受到伤害: ${damage}, 当前血量: ${this.currentHealth}`); this.currentHealth -= damage; if (this.currentHealth <= 0) { console.log('[Wall] 墙体血量为0,调用onWallDestroyed'); this.onWallDestroyed(); } } onWallDestroyed() { console.log('[Wall] 墙体被摧毁,触发GAME_DEFEAT事件'); this.eventBus.emit(GameEvents.GAME_DEFEAT); } } // 测试函数1:正常情况下的墙体失败 function testNormalWallDefeat() { console.log('\n=== 测试1:正常情况下的墙体失败 ==='); const eventBus = new MockEventBus(); const { canvas, gameEnd: gameEndNode } = createMockCanvasStructure(); const gameEnd = new MockGameEnd(gameEndNode, eventBus); const wall = new MockWall(eventBus); console.log('\n--- 初始状态 ---'); console.log('GameEnd状态:', gameEnd.getStatus()); console.log('\n--- 模拟墙体血量为0 ---'); wall.takeDamage(100); console.log('\n--- 检查结果 ---'); const status = gameEnd.getStatus(); console.log('GameEnd状态:', status); return { scenario: 'normal_wall_defeat', success: status.animationCount === 1 && status.isVisible, status: status }; } // 测试函数2:有其他UI面板干扰的情况 function testUIInterferenceWallDefeat() { console.log('\n=== 测试2:UI面板干扰情况下的墙体失败 ==='); const eventBus = new MockEventBus(); const { canvas, gameEnd: gameEndNode, pauseMenu, settingsPanel } = createMockCanvasStructure(); const gameEnd = new MockGameEnd(gameEndNode, eventBus); const wall = new MockWall(eventBus); console.log('\n--- 模拟其他UI面板激活 ---'); pauseMenu.active = true; settingsPanel.active = true; console.log('PauseMenu激活状态:', pauseMenu.active, 'siblingIndex:', pauseMenu.siblingIndex); console.log('SettingsPanel激活状态:', settingsPanel.active, 'siblingIndex:', settingsPanel.siblingIndex); console.log('\n--- 初始状态 ---'); console.log('GameEnd状态:', gameEnd.getStatus()); console.log('\n--- 模拟墙体血量为0 ---'); wall.takeDamage(100); console.log('\n--- 检查结果 ---'); const status = gameEnd.getStatus(); console.log('GameEnd状态:', status); return { scenario: 'ui_interference_wall_defeat', success: status.animationCount === 1 && status.isVisible, status: status, interference: { pauseMenuActive: pauseMenu.active, settingsPanelActive: settingsPanel.active } }; } // 测试函数3:GameEnd层级被调整的情况 function testLayerOrderWallDefeat() { console.log('\n=== 测试3:GameEnd层级被调整情况下的墙体失败 ==='); const eventBus = new MockEventBus(); const { canvas, gameEnd: gameEndNode, pauseMenu } = createMockCanvasStructure(); const gameEnd = new MockGameEnd(gameEndNode, eventBus); const wall = new MockWall(eventBus); console.log('\n--- 模拟GameEnd层级被意外调整到最底层 ---'); gameEndNode.setSiblingIndex(0); // 调整到最底层 pauseMenu.active = true; console.log('调整后的层级顺序:'); canvas.children.forEach((child, index) => { console.log(` ${index}: ${child.name} (siblingIndex: ${child.siblingIndex}, active: ${child.active})`); }); console.log('\n--- 初始状态 ---'); console.log('GameEnd状态:', gameEnd.getStatus()); console.log('\n--- 模拟墙体血量为0 ---'); wall.takeDamage(100); console.log('\n--- 检查结果 ---'); const status = gameEnd.getStatus(); console.log('GameEnd状态:', status); return { scenario: 'layer_order_wall_defeat', success: status.animationCount === 1 && status.isVisible, status: status, layerInfo: { gameEndSiblingIndex: gameEndNode.siblingIndex, pauseMenuSiblingIndex: pauseMenu.siblingIndex, pauseMenuActive: pauseMenu.active } }; } // 测试函数4:UI重置事件干扰 function testUIResetInterference() { console.log('\n=== 测试4:UI重置事件干扰情况 ==='); const eventBus = new MockEventBus(); const { canvas, gameEnd: gameEndNode } = createMockCanvasStructure(); const gameEnd = new MockGameEnd(gameEndNode, eventBus); const wall = new MockWall(eventBus); console.log('\n--- 初始状态 ---'); console.log('GameEnd状态:', gameEnd.getStatus()); console.log('\n--- 模拟墙体血量为0 ---'); wall.takeDamage(100); console.log('\n--- 模拟UI重置事件干扰 ---'); setTimeout(() => { eventBus.emit(GameEvents.RESET_UI_STATES); console.log('\n--- 检查UI重置后的结果 ---'); const statusAfterReset = gameEnd.getStatus(); console.log('UI重置后GameEnd状态:', statusAfterReset); }, 100); console.log('\n--- 检查初始结果 ---'); const status = gameEnd.getStatus(); console.log('GameEnd状态:', status); return { scenario: 'ui_reset_interference', success: status.animationCount === 1 && status.isVisible, status: status }; } // 运行所有测试 function runAllTests() { console.log('\n🔍 开始GameEnd节点状态调试测试'); const results = []; // 测试1:正常情况 results.push(testNormalWallDefeat()); // 测试2:UI干扰 results.push(testUIInterferenceWallDefeat()); // 测试3:层级问题 results.push(testLayerOrderWallDefeat()); // 测试4:UI重置干扰 results.push(testUIResetInterference()); console.log('\n=== 调试测试结果分析 ==='); results.forEach((result, index) => { console.log(`\n测试${index + 1} (${result.scenario}):`); console.log(' 测试通过:', result.success ? '✅' : '❌'); console.log(' 动画执行次数:', result.status.animationCount); console.log(' 面板可见性:', result.status.isVisible); console.log(' 节点激活状态:', result.status.nodeStatus.active); console.log(' 节点透明度:', result.status.nodeStatus.opacity); console.log(' 节点缩放:', result.status.nodeStatus.scale); console.log(' 节点层级:', result.status.nodeStatus.siblingIndex); if (result.interference) { console.log(' UI干扰情况:', result.interference); } if (result.layerInfo) { console.log(' 层级信息:', result.layerInfo); } }); const allPassed = results.every(r => r.success); console.log('\n=== 调试结论 ==='); if (allPassed) { console.log('🎉 所有测试通过!GameEnd节点状态正常。'); console.log('💡 如果实际游戏中仍有问题,可能是以下原因:'); console.log(' 1. 实际场景中的UI层级配置不同'); console.log(' 2. 其他组件在运行时修改了GameEnd节点状态'); console.log(' 3. 动画系统或渲染系统的问题'); console.log(' 4. GameEnd组件的某些属性在编辑器中配置不正确'); } else { console.log('⚠️ 发现潜在问题:'); const failedTests = results.filter(r => !r.success); failedTests.forEach(test => { console.log(` - ${test.scenario}: 可能的问题原因`); if (test.scenario.includes('interference')) { console.log(' → UI面板层级冲突,GameEnd被其他面板遮挡'); } if (test.scenario.includes('layer_order')) { console.log(' → GameEnd的siblingIndex被意外调整到较低层级'); } if (test.scenario.includes('reset')) { console.log(' → UI重置事件在不当时机触发,影响GameEnd显示'); } }); } return { allPassed, results, summary: { total: results.length, passed: results.filter(r => r.success).length, failed: results.filter(r => !r.success).length } }; } // 运行测试 const testResults = runAllTests(); console.log('\n📊 调试测试统计:'); console.log('总测试数:', testResults.summary.total); console.log('通过数:', testResults.summary.passed); console.log('失败数:', testResults.summary.failed); console.log('通过率:', Math.round(testResults.summary.passed / testResults.summary.total * 100) + '%'); if (testResults.allPassed) { console.log('\n✨ 调试结论:GameEnd节点逻辑正常,问题可能在实际游戏环境的配置或其他组件干扰!'); console.log('\n🔧 建议检查项目:'); console.log(' 1. 在Cocos Creator编辑器中检查GameEnd节点的层级位置'); console.log(' 2. 确认GameEnd组件的animationDuration属性设置正确(>0)'); console.log(' 3. 检查是否有其他脚本在运行时修改GameEnd节点状态'); console.log(' 4. 确认GameEnd节点在场景中的初始active状态'); console.log(' 5. 检查Canvas的渲染模式和UI摄像机设置'); } else { console.log('\n🔍 需要进一步调试的问题:'); testResults.results.forEach(result => { if (!result.success) { console.log(` - ${result.scenario}: 动画${result.status.animationCount}次,可见${result.status.isVisible}`); } }); }