使用Selenium与Robot类开发T-Rex游戏机器人时运行数秒后游戏即结束的问题咨询
T-Rex 自动操控游戏提前结束问题排查与解决方案
核心问题排查点
- 前置流程缺失
- 页面加载后未主动触发游戏启动:trex-runner 默认处于待机状态,需点击画布或按空格才能启动游戏,若未做启动标记,检测逻辑会与游戏运行状态错位。
- 浏览器窗口未获取焦点:
Robot类发送的是系统级按键,只有当前激活窗口能接收。若刚打开 Chrome 时焦点落在地址栏、或是运行中切走窗口,所有跳跃按键都会失效,几秒后撞到障碍物就结束运行。 - 未等待画布渲染完成:执行完
driver.get()立刻开始坐标检测时,游戏画布尚未渲染完成,取色坐标全部对应错误的页面区域,完全无法识别障碍物。
- 像素检测逻辑缺陷
- 坐标体系错误:
Robot.getPixelColor()接收的是屏幕绝对坐标,不是浏览器内相对坐标。硬编码的(460,520)没有排除 Chrome 顶部地址栏、书签栏的高度,最大化窗口后该位置实际对应页面空白区域或 T-Rex 身后位置,根本检测不到前方障碍物。 - 无检测去重机制:11*11 的嵌套循环会让同一个仙人掌被多个坐标点同时命中,短时间内反复触发跳跃、按下逻辑,甚至刚起跳就被误触发向下按键,导致滞空时间不足直接撞障。
- 颜色匹配无容错:硬编码匹配
new Color(83,83,83)时,若存在深色模式、显示器色彩校准偏差,仙人掌像素值与预设值存在细微差异,就会直接导致检测失效。
- 坐标体系错误:
- 运行节奏不合理
- 主循环无休眠间隔:
while(true)未加任何休眠,CPU 被占满后会导致 Robot 取色、按键响应延迟,同时 Chrome 渲染掉帧,游戏运行速度超出预期,几秒内就会撞上高速移动的障碍物。 - 起跳时机错位:检测到障碍物立刻起跳,没有考虑障碍物与 T-Rex 的实际距离,若检测到的是远处仙人掌,起跳太早会提前落地,刚好在仙人掌位置撞击。
- 主循环无休眠间隔:
修正后参考代码
public static void main(String[] args) throws InterruptedException, AWTException { // 配置Chrome启动参数,减少浏览器UI对坐标的干扰 ChromeOptions options = new ChromeOptions(); options.addArguments("--start-maximized"); options.addArguments("--disable-blink-features=AutomationControlled"); System.setProperty("webdriver.chrome.driver", "C:\\Users\\BHEL\\Downloads\\chromedriver_win32\\chromedriver.exe"); WebDriver driver = new ChromeDriver(options); driver.get("https://trex-runner.com/"); // 等待游戏画布渲染完成 new WebDriverWait(driver, Duration.ofSeconds(5)).until( ExpectedConditions.presenceOfElementLocated(By.tagName("canvas")) ); // 点击画布触发游戏启动,同时让浏览器获得焦点 WebElement gameCanvas = driver.findElement(By.tagName("canvas")); gameCanvas.click(); Robot robo = new Robot(); // 校准后的屏幕绝对检测坐标,避开顶部浏览器UI区域 final int CHECK_X = 600; final int CHECK_Y = 750; boolean isJumping = false; // 跳跃状态锁,避免重复触发 while(true) { // 主循环加50ms休眠,降低CPU占用 Thread.sleep(50); Color currentColor = robo.getPixelColor(CHECK_X, CHECK_Y); // 带10容差的颜色匹配,避免色彩偏差导致检测失效 boolean hasObstacle = Math.abs(currentColor.getRed() - 83) < 10 && Math.abs(currentColor.getGreen() - 83) < 10 && Math.abs(currentColor.getBlue() - 83) < 10; if(hasObstacle && !isJumping) { isJumping = true; robo.keyPress(KeyEvent.VK_UP); robo.keyRelease(KeyEvent.VK_UP); // 固定滞空时长,保证跳跃高度足够 Thread.sleep(250); // 落地后按下键加速通过障碍 robo.keyPress(KeyEvent.VK_DOWN); Thread.sleep(100); robo.keyRelease(KeyEvent.VK_DOWN); // 冷却时间,避免同一个障碍物重复触发 Thread.sleep(300); isJumping = false; } } }
注意:代码中的检测坐标需要根据自身屏幕分辨率、Chrome工具栏实际高度微调,可通过截屏工具定位 T-Rex 前方100像素左右的屏幕绝对坐标,保证检测位置刚好在 T-Rex 起跳前能识别到障碍物即可。
内容的提问来源于stack exchange,提问作者Yeshwin Verma
相关产品推荐
相关产品推荐

