| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573 |
- /**
- * 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}`);
- }
- });
- }
|