test_enhanced_anti_trap.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /**
  2. * 增强防围困机制测试脚本
  3. * 专门测试长距离振荡检测和干预功能
  4. *
  5. * 使用方法:
  6. * 1. 确保BallController.ts中testMode = true
  7. * 2. 在浏览器控制台运行此脚本
  8. * 3. 观察控制台输出和小球行为
  9. */
  10. // 测试配置
  11. const TEST_CONFIG = {
  12. // 测试持续时间(秒)
  13. testDuration: 60,
  14. // 监控间隔(毫秒)
  15. monitorInterval: 1000,
  16. // 预期的振荡检测触发次数
  17. expectedOscillationTriggers: 2,
  18. // 测试场景
  19. scenarios: [
  20. {
  21. name: "水平振荡测试",
  22. description: "小球在左右墙体间来回弹跳",
  23. expectedAxis: "horizontal"
  24. },
  25. {
  26. name: "垂直振荡测试",
  27. description: "小球在上下墙体间来回弹跳",
  28. expectedAxis: "vertical"
  29. },
  30. {
  31. name: "长距离方块振荡测试",
  32. description: "小球在距离较远的方块间来回弹跳",
  33. expectedAxis: "horizontal" // 或 "vertical"
  34. }
  35. ]
  36. };
  37. // 测试状态
  38. let testState = {
  39. startTime: 0,
  40. oscillationTriggers: 0,
  41. directionChanges: 0,
  42. lastPosition: null,
  43. positionHistory: [],
  44. testResults: []
  45. };
  46. /**
  47. * 开始增强防围困机制测试
  48. */
  49. function startEnhancedAntiTrapTest() {
  50. console.log("\n=== 增强防围困机制测试开始 ===");
  51. console.log("测试目标:验证长距离振荡检测和干预功能");
  52. console.log("测试时长:" + TEST_CONFIG.testDuration + "秒");
  53. console.log("\n请确保:");
  54. console.log("1. BallController中testMode = true");
  55. console.log("2. 小球已启动并开始运动");
  56. console.log("3. 场景中有适当的墙体或方块布局\n");
  57. // 重置测试状态
  58. testState.startTime = Date.now();
  59. testState.oscillationTriggers = 0;
  60. testState.directionChanges = 0;
  61. testState.lastPosition = null;
  62. testState.positionHistory = [];
  63. testState.testResults = [];
  64. // 开始监控
  65. startMonitoring();
  66. // 设置测试结束定时器
  67. setTimeout(() => {
  68. endTest();
  69. }, TEST_CONFIG.testDuration * 1000);
  70. }
  71. /**
  72. * 开始监控小球状态
  73. */
  74. function startMonitoring() {
  75. const monitorInterval = setInterval(() => {
  76. if (Date.now() - testState.startTime >= TEST_CONFIG.testDuration * 1000) {
  77. clearInterval(monitorInterval);
  78. return;
  79. }
  80. monitorBallState();
  81. }, TEST_CONFIG.monitorInterval);
  82. // 监听控制台输出(模拟)
  83. interceptConsoleLog();
  84. }
  85. /**
  86. * 监控小球状态
  87. */
  88. function monitorBallState() {
  89. // 这里需要根据实际的Cocos Creator API来获取小球状态
  90. // 以下是示例代码,需要根据实际情况调整
  91. try {
  92. // 获取小球节点(需要根据实际场景结构调整)
  93. const gameArea = cc.find('Canvas/GameLevelUI/GameArea');
  94. if (!gameArea) {
  95. console.log("[测试] 未找到GameArea节点");
  96. return;
  97. }
  98. const balls = gameArea.children.filter(child =>
  99. child.name === 'Ball' || child.name === 'AdditionalBall'
  100. );
  101. if (balls.length === 0) {
  102. console.log("[测试] 未找到小球节点");
  103. return;
  104. }
  105. const ball = balls[0];
  106. const currentPos = ball.getWorldPosition();
  107. // 记录位置历史
  108. testState.positionHistory.push({
  109. x: currentPos.x,
  110. y: currentPos.y,
  111. time: Date.now()
  112. });
  113. // 保持历史记录在合理范围内
  114. if (testState.positionHistory.length > 50) {
  115. testState.positionHistory.shift();
  116. }
  117. // 检测方向改变
  118. if (testState.lastPosition) {
  119. const deltaX = currentPos.x - testState.lastPosition.x;
  120. const deltaY = currentPos.y - testState.lastPosition.y;
  121. // 简单的方向改变检测
  122. if (Math.abs(deltaX) > 10 || Math.abs(deltaY) > 10) {
  123. testState.directionChanges++;
  124. }
  125. }
  126. testState.lastPosition = { x: currentPos.x, y: currentPos.y };
  127. // 分析运动模式
  128. analyzeMovementPattern();
  129. } catch (error) {
  130. console.log("[测试] 监控过程中出现错误:", error.message);
  131. }
  132. }
  133. /**
  134. * 分析运动模式
  135. */
  136. function analyzeMovementPattern() {
  137. if (testState.positionHistory.length < 10) {
  138. return;
  139. }
  140. const recent = testState.positionHistory.slice(-10);
  141. let minX = recent[0].x, maxX = recent[0].x;
  142. let minY = recent[0].y, maxY = recent[0].y;
  143. for (const pos of recent) {
  144. minX = Math.min(minX, pos.x);
  145. maxX = Math.max(maxX, pos.x);
  146. minY = Math.min(minY, pos.y);
  147. maxY = Math.max(maxY, pos.y);
  148. }
  149. const xRange = maxX - minX;
  150. const yRange = maxY - minY;
  151. // 检测振荡模式
  152. let detectedPattern = 'none';
  153. if (xRange > 100 && yRange < 50) {
  154. detectedPattern = 'horizontal';
  155. } else if (yRange > 100 && xRange < 50) {
  156. detectedPattern = 'vertical';
  157. }
  158. if (detectedPattern !== 'none') {
  159. console.log(`[测试] 检测到${detectedPattern === 'horizontal' ? '水平' : '垂直'}振荡模式`);
  160. console.log(`[测试] X范围: ${xRange.toFixed(1)}, Y范围: ${yRange.toFixed(1)}`);
  161. }
  162. }
  163. /**
  164. * 拦截控制台输出以统计防围困触发次数
  165. */
  166. function interceptConsoleLog() {
  167. const originalLog = console.log;
  168. console.log = function(...args) {
  169. const message = args.join(' ');
  170. // 检测振荡检测触发
  171. if (message.includes('[防围困] 检测到小球') && message.includes('振荡')) {
  172. testState.oscillationTriggers++;
  173. testState.testResults.push({
  174. time: Date.now() - testState.startTime,
  175. type: 'oscillation_detected',
  176. message: message
  177. });
  178. }
  179. // 检测增强防围困触发
  180. if (message.includes('[防围困] 触发增强防围困机制')) {
  181. testState.testResults.push({
  182. time: Date.now() - testState.startTime,
  183. type: 'enhanced_anti_trap_triggered',
  184. message: message
  185. });
  186. }
  187. // 检测冲量应用
  188. if (message.includes('[防围困]') && (message.includes('冲量') || message.includes('处理'))) {
  189. testState.testResults.push({
  190. time: Date.now() - testState.startTime,
  191. type: 'impulse_applied',
  192. message: message
  193. });
  194. }
  195. // 调用原始console.log
  196. originalLog.apply(console, args);
  197. };
  198. }
  199. /**
  200. * 结束测试并生成报告
  201. */
  202. function endTest() {
  203. console.log("\n=== 增强防围困机制测试结束 ===");
  204. const testDuration = (Date.now() - testState.startTime) / 1000;
  205. console.log("\n📊 测试统计:");
  206. console.log(`⏱️ 测试时长: ${testDuration.toFixed(1)}秒`);
  207. console.log(`🔄 方向改变次数: ${testState.directionChanges}`);
  208. console.log(`🎯 振荡检测触发次数: ${testState.oscillationTriggers}`);
  209. console.log(`📝 总事件记录: ${testState.testResults.length}`);
  210. console.log("\n📋 详细事件记录:");
  211. testState.testResults.forEach((result, index) => {
  212. const timeStr = (result.time / 1000).toFixed(1) + 's';
  213. console.log(`${index + 1}. [${timeStr}] ${result.type}: ${result.message}`);
  214. });
  215. // 生成测试结论
  216. generateTestConclusion();
  217. }
  218. /**
  219. * 生成测试结论
  220. */
  221. function generateTestConclusion() {
  222. console.log("\n🎯 测试结论:");
  223. const oscillationDetected = testState.oscillationTriggers > 0;
  224. const enhancedAntiTrapTriggered = testState.testResults.some(r => r.type === 'enhanced_anti_trap_triggered');
  225. const impulseApplied = testState.testResults.some(r => r.type === 'impulse_applied');
  226. if (oscillationDetected) {
  227. console.log("✅ 振荡检测功能正常工作");
  228. } else {
  229. console.log("❌ 未检测到振荡模式,可能需要调整参数或测试场景");
  230. }
  231. if (enhancedAntiTrapTriggered) {
  232. console.log("✅ 增强防围困机制成功触发");
  233. } else {
  234. console.log("❌ 增强防围困机制未触发");
  235. }
  236. if (impulseApplied) {
  237. console.log("✅ 冲量干预成功应用");
  238. } else {
  239. console.log("❌ 未检测到冲量干预");
  240. }
  241. // 总体评估
  242. const successCount = [oscillationDetected, enhancedAntiTrapTriggered, impulseApplied].filter(Boolean).length;
  243. const totalTests = 3;
  244. const successRate = (successCount / totalTests * 100).toFixed(1);
  245. console.log(`\n📈 总体成功率: ${successRate}% (${successCount}/${totalTests})`);
  246. if (successRate >= 66.7) {
  247. console.log("🎉 增强防围困机制测试通过!");
  248. } else {
  249. console.log("⚠️ 增强防围困机制需要进一步调优");
  250. console.log("\n🔧 建议调整:");
  251. if (!oscillationDetected) {
  252. console.log("- 降低directionChangeThreshold(当前4次,建议2-3次)");
  253. console.log("- 减小oscillationDistanceThreshold(当前100,建议50-80)");
  254. }
  255. if (!enhancedAntiTrapTriggered) {
  256. console.log("- 检查小球是否真的在振荡");
  257. console.log("- 确认testMode已启用");
  258. }
  259. if (!impulseApplied) {
  260. console.log("- 检查冲量计算逻辑");
  261. console.log("- 确认RigidBody2D组件正常工作");
  262. }
  263. }
  264. }
  265. /**
  266. * 快速测试函数(简化版)
  267. */
  268. function quickEnhancedAntiTrapTest() {
  269. console.log("🚀 快速增强防围困测试(30秒)");
  270. TEST_CONFIG.testDuration = 30;
  271. startEnhancedAntiTrapTest();
  272. }
  273. // 导出测试函数
  274. if (typeof window !== 'undefined') {
  275. window.startEnhancedAntiTrapTest = startEnhancedAntiTrapTest;
  276. window.quickEnhancedAntiTrapTest = quickEnhancedAntiTrapTest;
  277. }
  278. console.log("\n🔧 增强防围困机制测试脚本已加载");
  279. console.log("使用方法:");
  280. console.log("- startEnhancedAntiTrapTest() // 完整测试(60秒)");
  281. console.log("- quickEnhancedAntiTrapTest() // 快速测试(30秒)");
  282. console.log("\n⚠️ 注意:确保BallController中testMode = true");