| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431 |
- /**
- * 综合失败场景测试
- * 模拟实际游戏中的复杂情况,包括UI层级、其他组件干扰等
- */
- // 模拟事件系统
- 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',
- CURRENCY_CHANGED: 'CURRENCY_CHANGED'
- };
- // 模拟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);
- }
- }
- // 模拟MenuController(修复后的版本)
- class MockMenuController {
- constructor(eventBus) {
- this.eventBus = eventBus;
- this.isMenuOpen = false;
- this.currentAppState = 'IN_GAME';
- }
-
- async onBackButtonClick() {
- console.log('[MenuController] 返回按钮被点击');
-
- if (this.currentAppState === 'IN_GAME') {
- console.log('[MenuController] 游戏中退出,触发GAME_DEFEAT事件显示游戏失败UI');
-
- // 先触发游戏失败事件,让GameEnd面板显示
- this.eventBus.emit(GameEvents.GAME_DEFEAT);
-
- // 关闭菜单(不触发GAME_RESUME事件,避免事件冲突)
- await this.closeMenuWithoutResume();
-
- console.log('[MenuController] 菜单退出处理完成,已触发GAME_DEFEAT事件');
- }
- }
-
- async closeMenuWithoutResume() {
- if (!this.isMenuOpen) return;
-
- this.isMenuOpen = false;
- console.log('[MenuController] 菜单已关闭(未触发游戏恢复)');
- }
- }
- // 模拟GameEnd组件(完整版本)
- class MockGameEnd {
- constructor(eventBus) {
- this.eventBus = eventBus;
- this.animationCount = 0;
- this.isVisible = false;
- this.hasProcessedGameEnd = false;
- this.currentRewards = { money: -1, diamonds: -1 };
- this.isGameSuccess = false;
- this.hasDoubledReward = false;
- this.setupEventListeners();
- }
-
- setupEventListeners() {
- console.log('[GameEnd] 设置事件监听器');
- this.eventBus.on(GameEvents.GAME_DEFEAT, this.onGameDefeat, this);
- this.eventBus.on(GameEvents.GAME_START, this.onGameStart, this);
- this.eventBus.on(GameEvents.RESET_UI_STATES, this.onResetUI, this);
- }
-
- onGameDefeat() {
- console.log('[GameEnd] 接收到GAME_DEFEAT事件');
- console.log('[GameEnd] 游戏失败事件处理,开始统一处理流程');
-
- this.isGameSuccess = false;
- this.calculateAndShowRewards();
- }
-
- calculateAndShowRewards() {
- if (this.hasProcessedGameEnd) {
- console.log('[GameEnd] 游戏结束已处理过,跳过重复计算');
- return;
- }
-
- this.hasProcessedGameEnd = true;
- console.log('[GameEnd] 计算和显示奖励');
-
- // 模拟奖励计算
- this.currentRewards = { money: 50, diamonds: 2 };
-
- this.showEndPanelWithAnimation();
- }
-
- showEndPanelWithAnimation() {
- console.log('[GameEnd] 开始显示结算面板动画');
- this.animationCount++;
- this.isVisible = true;
- console.log(`[GameEnd] GameEnd面板弹出动画第${this.animationCount}次执行`);
- }
-
- onGameStart() {
- console.log('[GameEnd] 收到游戏开始事件,重置奖励显示');
- this.currentRewards = { money: 0, diamonds: 0 };
- this.hasProcessedGameEnd = false;
- this.hasDoubledReward = false;
- this.isGameSuccess = false;
- this.animationCount = 0;
- this.isVisible = false;
- }
-
- onResetUI() {
- console.log('[GameEnd] 重置UI状态');
-
- // 重置所有状态,为下一局游戏做准备
- this.hasDoubledReward = false;
- // 注意:不重置currentRewards,保持奖励显示直到下次游戏开始
- this.isGameSuccess = false;
- this.hasProcessedGameEnd = false;
-
- console.log('[GameEnd] UI状态重置完成');
- }
-
- getStatus() {
- return {
- animationCount: this.animationCount,
- isVisible: this.isVisible,
- hasProcessedGameEnd: this.hasProcessedGameEnd,
- currentRewards: { ...this.currentRewards },
- isGameSuccess: this.isGameSuccess
- };
- }
- }
- // 模拟UIStateManager
- class MockUIStateManager {
- constructor(eventBus) {
- this.eventBus = eventBus;
- this.setupEventListeners();
- }
-
- setupEventListeners() {
- this.eventBus.on(GameEvents.RESET_UI_STATES, this.onResetUI, this);
- }
-
- onResetUI() {
- console.log('[UIStateManager] 接收到RESET_UI_STATES事件');
- // 可能会影响其他UI组件
- }
- }
- // 模拟GameManager
- class MockGameManager {
- constructor(eventBus) {
- this.eventBus = eventBus;
- this.gameState = 'PLAYING';
- this.setupEventListeners();
- }
-
- setupEventListeners() {
- this.eventBus.on(GameEvents.GAME_DEFEAT, this.onGameDefeat, this);
- }
-
- onGameDefeat() {
- console.log('[GameManager] 接收到GAME_DEFEAT事件');
- this.gameState = 'DEFEAT';
- console.log('[GameManager] 游戏状态切换为DEFEAT');
- }
-
- onMainMenuClick() {
- console.log('[GameManager] 主菜单按钮被点击');
- // 可能触发RESET_UI_STATES事件
- this.eventBus.emit(GameEvents.RESET_UI_STATES);
- }
- }
- // 模拟MainUIController
- class MockMainUIController {
- constructor(eventBus) {
- this.eventBus = eventBus;
- this.setupEventListeners();
- }
-
- setupEventListeners() {
- this.eventBus.on(GameEvents.CURRENCY_CHANGED, this.onCurrencyChanged, this);
- }
-
- onCurrencyChanged() {
- console.log('[MainUIController] 货币变化事件处理');
- }
-
- onReturnToMainUI() {
- console.log('[MainUIController] 返回主界面');
- this.eventBus.emit(GameEvents.CURRENCY_CHANGED);
- }
- }
- // 测试函数1:墙体血量为0场景
- function testWallDefeatScenario() {
- console.log('\n=== 测试1:墙体血量为0失败场景 ===');
-
- const eventBus = new MockEventBus();
- const wall = new MockWall(eventBus);
- const gameEnd = new MockGameEnd(eventBus);
- const gameManager = new MockGameManager(eventBus);
- const uiStateManager = new MockUIStateManager(eventBus);
- const mainUIController = new MockMainUIController(eventBus);
-
- console.log('\n--- 初始状态 ---');
- console.log('墙体血量:', wall.currentHealth);
- console.log('GameEnd状态:', gameEnd.getStatus());
-
- console.log('\n--- 模拟墙体受到致命伤害 ---');
- wall.takeDamage(100);
-
- console.log('\n--- 检查结果 ---');
- const status = gameEnd.getStatus();
- console.log('GameEnd状态:', status);
-
- return {
- scenario: 'wall_defeat',
- success: status.animationCount === 1 && status.isVisible,
- status: status,
- eventLog: eventBus.getEventLog()
- };
- }
- // 测试函数2:菜单退出场景
- function testMenuDefeatScenario() {
- console.log('\n=== 测试2:菜单退出失败场景 ===');
-
- const eventBus = new MockEventBus();
- const menuController = new MockMenuController(eventBus);
- const gameEnd = new MockGameEnd(eventBus);
- const gameManager = new MockGameManager(eventBus);
- const uiStateManager = new MockUIStateManager(eventBus);
- const mainUIController = new MockMainUIController(eventBus);
-
- console.log('\n--- 初始状态 ---');
- console.log('GameEnd状态:', gameEnd.getStatus());
-
- console.log('\n--- 模拟菜单退出 ---');
- menuController.onBackButtonClick();
-
- console.log('\n--- 检查结果 ---');
- const status = gameEnd.getStatus();
- console.log('GameEnd状态:', status);
-
- return {
- scenario: 'menu_defeat',
- success: status.animationCount === 1 && status.isVisible,
- status: status,
- eventLog: eventBus.getEventLog()
- };
- }
- // 测试函数3:UI重置干扰场景
- function testUIResetInterferenceScenario() {
- console.log('\n=== 测试3:UI重置干扰场景 ===');
-
- const eventBus = new MockEventBus();
- const wall = new MockWall(eventBus);
- const gameEnd = new MockGameEnd(eventBus);
- const gameManager = new MockGameManager(eventBus);
- const uiStateManager = new MockUIStateManager(eventBus);
- const mainUIController = new MockMainUIController(eventBus);
-
- console.log('\n--- 初始状态 ---');
- console.log('GameEnd状态:', gameEnd.getStatus());
-
- console.log('\n--- 模拟墙体血量为0 ---');
- wall.takeDamage(100);
-
- console.log('\n--- 模拟UI重置事件干扰 ---');
- gameManager.onMainMenuClick(); // 触发RESET_UI_STATES
-
- console.log('\n--- 检查结果 ---');
- const status = gameEnd.getStatus();
- console.log('GameEnd状态:', status);
-
- return {
- scenario: 'ui_reset_interference',
- success: status.animationCount === 1 && status.isVisible && status.currentRewards.money > 0,
- status: status,
- eventLog: eventBus.getEventLog()
- };
- }
- // 运行所有测试
- function runAllTests() {
- console.log('\n🧪 开始综合失败场景测试');
-
- const results = [];
-
- // 测试1:墙体血量为0
- results.push(testWallDefeatScenario());
-
- // 测试2:菜单退出
- results.push(testMenuDefeatScenario());
-
- // 测试3:UI重置干扰
- results.push(testUIResetInterferenceScenario());
-
- 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.currentRewards);
- console.log(' 处理状态:', result.status.hasProcessedGameEnd);
-
- const defeatEvents = result.eventLog.filter(log => log.event === GameEvents.GAME_DEFEAT);
- const resumeEvents = result.eventLog.filter(log => log.event === GameEvents.GAME_RESUME);
- const resetEvents = result.eventLog.filter(log => log.event === GameEvents.RESET_UI_STATES);
-
- console.log(' GAME_DEFEAT事件:', defeatEvents.length);
- console.log(' GAME_RESUME事件:', resumeEvents.length);
- console.log(' RESET_UI_STATES事件:', resetEvents.length);
- });
-
- const allPassed = results.every(r => r.success);
- console.log('\n=== 最终结果 ===');
- if (allPassed) {
- console.log('🎉 所有测试通过!失败处理流程工作正常。');
- } else {
- console.log('⚠️ 部分测试失败,需要进一步调试。');
-
- const failedTests = results.filter(r => !r.success);
- console.log('失败的测试场景:');
- failedTests.forEach(test => {
- console.log(` - ${test.scenario}`);
- });
- }
-
- 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✨ 综合测试结论:失败处理流程已完全修复,两种失败场景都能正常工作!');
- } else {
- console.log('\n🔍 需要进一步调试的问题:');
- testResults.results.forEach(result => {
- if (!result.success) {
- console.log(` - ${result.scenario}: 动画${result.status.animationCount}次,可见${result.status.isVisible}`);
- }
- });
- }
|