/** * 测试墙体血量为0和菜单退出两种失败场景的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 }); } emit(event, ...args) { this.eventLog.push({ event, args, timestamp: Date.now() }); console.log(`[EventBus] 触发事件: ${event}`); if (this.listeners.has(event)) { this.listeners.get(event).forEach(({ callback, context }) => { callback.call(context, ...args); }); } } getEventLog() { return this.eventLog; } clearLog() { this.eventLog = []; } } // 模拟GameEvents const GameEvents = { GAME_DEFEAT: 'GAME_DEFEAT', WALL_DESTROYED: 'WALL_DESTROYED', GAME_RESUME: 'GAME_RESUME' }; // 模拟AppState const AppState = { IN_GAME: 'in_game' }; // 模拟Wall组件 class MockWall { constructor(eventBus) { this.eventBus = eventBus; this.currentHealth = 100; this.maxHealth = 100; } takeDamage(damage) { this.currentHealth -= damage; console.log(`[Wall] 墙体受到伤害: ${damage}, 当前血量: ${this.currentHealth}`); if (this.currentHealth <= 0) { this.onWallDestroyed(); } } onWallDestroyed() { console.log('[Wall] 墙体被摧毁,触发游戏失败'); // 通过事件系统触发墙体被摧毁事件(保留用于其他监听器) this.eventBus.emit(GameEvents.WALL_DESTROYED, { finalHealth: this.currentHealth, maxHealth: this.maxHealth }); // 统一失败处理:直接触发GAME_DEFEAT事件,与菜单退出处理保持一致 console.log('[Wall] 直接触发GAME_DEFEAT事件,与菜单退出失败处理流程一致'); this.eventBus.emit(GameEvents.GAME_DEFEAT); } } // 模拟MenuController class MockMenuController { constructor(eventBus, gameManager) { this.eventBus = eventBus; this.gameManager = gameManager; this.isMenuOpen = false; } async closeMenuWithoutResume() { if (!this.isMenuOpen) return; this.isMenuOpen = false; console.log('[MenuController] 菜单已关闭(未触发游戏恢复)'); } async onBackButtonClick() { console.log('[MenuController] 退出游戏按钮被点击'); const currentAppState = this.gameManager.getCurrentAppState(); console.log(`[MenuController] 当前应用状态: ${currentAppState}`); if (currentAppState === AppState.IN_GAME) { console.log('[MenuController] 游戏中退出,触发GAME_DEFEAT事件显示游戏失败UI'); // 先触发游戏失败事件 this.eventBus.emit(GameEvents.GAME_DEFEAT); // 关闭菜单(不触发GAME_RESUME事件) await this.closeMenuWithoutResume(); console.log('[MenuController] 菜单退出处理完成,已触发GAME_DEFEAT事件'); } } } // 模拟GameManager class MockGameManager { constructor() { this.currentAppState = AppState.IN_GAME; } getCurrentAppState() { return this.currentAppState; } } // 模拟GameEnd组件 class MockGameEnd { constructor(eventBus) { this.eventBus = eventBus; this.defeatProcessed = 0; this.animationShown = 0; this.setupEventListeners(); } setupEventListeners() { this.eventBus.on(GameEvents.GAME_DEFEAT, this.onGameDefeat, this); console.log('[GameEnd] 已注册GAME_DEFEAT事件监听器'); } onGameDefeat() { console.log('[GameEnd] 接收到GAME_DEFEAT事件'); console.log('[GameEnd] 游戏失败事件处理,开始统一处理流程'); this.defeatProcessed++; this.calculateAndShowRewards(); } calculateAndShowRewards() { console.log('[GameEnd] 计算和显示奖励(包含面板动画显示)'); this.animationShown++; } } // 测试函数 function testBothDefeatScenarios() { console.log('=== 测试墙体血量为0和菜单退出两种失败场景 ===\n'); const eventBus = new MockEventBus(); const gameManager = new MockGameManager(); const menuController = new MockMenuController(eventBus, gameManager); const gameEnd = new MockGameEnd(eventBus); const wall = new MockWall(eventBus); console.log('1. 测试墙体血量为0场景:'); eventBus.clearLog(); wall.takeDamage(100); // 墙体血量归零 console.log('\n2. 测试菜单退出场景:'); menuController.onBackButtonClick(); console.log('\n=== 事件触发分析 ==='); const eventLog = eventBus.getEventLog(); eventLog.forEach((log, index) => { console.log(`${index + 1}. 事件: ${log.event}`); }); console.log('\n=== 验证结果 ==='); console.log(`GameEnd处理GAME_DEFEAT事件次数: ${gameEnd.defeatProcessed}`); console.log(`GameEnd显示动画次数: ${gameEnd.animationShown}`); // 分析事件 const gameDefeatEvents = eventLog.filter(log => log.event === GameEvents.GAME_DEFEAT); const wallDestroyedEvents = eventLog.filter(log => log.event === GameEvents.WALL_DESTROYED); const gameResumeEvents = eventLog.filter(log => log.event === GameEvents.GAME_RESUME); console.log(`\n=== 事件统计 ===`); console.log(`GAME_DEFEAT事件数量: ${gameDefeatEvents.length}`); console.log(`WALL_DESTROYED事件数量: ${wallDestroyedEvents.length}`); console.log(`GAME_RESUME事件数量: ${gameResumeEvents.length}`); console.log(`\n=== 问题诊断 ===`); if (gameEnd.defeatProcessed === 2 && gameEnd.animationShown === 2) { console.log('✅ 两种失败场景都正确触发了GameEnd动画'); } else { console.log('❌ 存在问题:某些失败场景没有正确触发GameEnd动画'); console.log(` - 预期处理次数: 2, 实际处理次数: ${gameEnd.defeatProcessed}`); console.log(` - 预期动画次数: 2, 实际动画次数: ${gameEnd.animationShown}`); } if (gameDefeatEvents.length === 2) { console.log('✅ 两种场景都正确触发了GAME_DEFEAT事件'); } else { console.log('❌ GAME_DEFEAT事件触发异常'); } if (gameResumeEvents.length === 0) { console.log('✅ 没有事件冲突(无GAME_RESUME事件)'); } else { console.log('❌ 存在事件冲突(检测到GAME_RESUME事件)'); } } // 运行测试 testBothDefeatScenarios();