基于 OpenCV 计算机视觉的微信「跳一跳」全自动辅助工具。通过实时截取游戏画面、识别棋子与目标落点、精准计算按压时长,实现无人值守自动跳跃。支持双算法引擎、无限循环刷分、现代化暗色 GUI 界面。
| 特性 | 说明 |
|---|---|
| 🔬 双算法引擎 | 自研 HSV 峰值检测算法 + 移植自小红书的 BFS 洪水填充算法,可运行时热切换 |
| 🔁 双游戏模式 | 单局模式:跳完自动停止并统计次数;无限模式:自动检测游戏结束并点击"再玩一局" |
| 👁️ 实时画面预览 | 右侧面板实时显示游戏截图,标注棋子位置(红点)、目标落点(蓝点)、跳跃轨迹(黄线) |
| 🎚️ 参数实时可调 | 按压系数和跳跃间隔在界面上直接修改,无需重启 |
| 🛡️ 防抢夺保护 | 启用 pyautogui.FAILSAFE,鼠标移至屏幕左上角即可紧急停止 |
| 🎨 暗色主题 UI | 基于 CustomTkinter 构建,仿 Spotify 风格的深绿配色方案 |
| 📦 单文件 EXE | 通过 PyInstaller 打包,无需安装 Python 环境即可运行 |
┌─────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ 截取游戏 │───▶│ 棋子识别 │───▶│ 目标识别 │───▶│ 距离计算 │───▶│ 模拟按压 │
│ 窗口画面 │ │ (self) │ │ (goal) │ │ d=√Δx²+Δy²│ │ t = d×k │
└─────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘
│ │
│ mss 截图 (BGR) │ pyautogui
│ 缩放到 612×1151 │ mouseDown/mouseUp
│ │
└────────────────────── 等待 2.5s ──────────────────────────────┘
棋子识别 — 跳一跳的棋子在游戏中呈现为独特的蓝紫色,利用这一特征在 HSV 色彩空间中进行检测:
- 截取图像下半部(30%~80% 高度区域),排除顶部天空和底部干扰
- 转换到 HSV 色彩空间,设定紫色范围
H:[105,140] S:[20,130] V:[40,140] - 形态学开运算去除噪声,提取最大轮廓
- 取轮廓边界框底边中点作为棋子底部中心坐标
原始图像 ──▶ HSV 转换 ──▶ 颜色阈值过滤 ──▶ 开运算去噪 ──▶ 最大轮廓 ──▶ 底部中心 = 棋子坐标
目标识别 — 核心思路是利用棋子的位置判断下一个方块在左边还是右边,然后在对应半区沿垂直方向扫描:
- 判断棋子位于画面左半侧还是右半侧,目标必然在另一侧
- 在目标侧的对侧边缘采样背景色
- 从上往下逐行扫描,对比每行像素与背景色的差异
- 连续多行检测到差异像素时标记为"命中"
- 在命中区域内逐行计算前景宽度,取宽度最大的行为目标中心所在行
该算法移植自 burningcl/wechat_jump_hack,原始作者为小红书团队的 chenliang,包含三个核心模块:
| 模块 | 对应类 | 功能 |
|---|---|---|
| MyPosFinder | java_self_detect() |
RGB 颜色容差匹配定位棋子 |
| NextCenterFinder | _next_center_find() |
背景色采样 + BFS 洪水填充定位目标 |
| WhitePointFinder | _white_point_find() |
搜索白色中心圆点获取精确坐标 |
| BottleFinder | _bottle_find() |
处理全白瓶子的特殊情况 |
算法流程:
1. 采样背景色 ──▶ 顶部行和底部行取色,建立 RGB 容差范围 [min-16, max+16]
2. 扫描目标顶点 ──▶ 从画面 1/4 处向下扫描,找到第一个非背景色像素
仅扫描与棋子水平距离 ≤ 垂直距离的像素(排除正下方区域)
3. 采样目标颜色 ──▶ 从顶点向下取 5 个像素的平均 RGB
4. BFS 洪水填充 ──▶ 从顶点出发,用 BFS 遍历所有容差范围内的同色像素
记录最左点 (leftX, leftY) 和最右点 (rightX, rightY)
5. 白色中心点 ──▶ 搜索目标下方 120×180 区域内 245,245,245 的白色圆点
尺寸 35~45 × 20~30 像素 → 直接用于中心坐标
6. 计算中心 ──▶ 有白色中心点:用白色中心点
无白色中心点:取最左点和最右点的中点
按压时长 (ms) = √((Δx)² + (Δy)²) × 按压系数
Δx、Δy:棋子坐标与目标坐标的水平和垂直像素差- 按压系数:默认 2.0,与屏幕 DPI 和窗口大小相关
- 每次跳跃叠加 ±0.02 的随机抖动,模拟人类操作的不确定性
- 最小按压时长 200ms,防止因距离过近导致无效点击
无限模式下,连续 3 次未能识别到棋子时触发结束检测:
- 截取画面 60%~83% 高度区域(排除底部广告干扰)
- 在 HSV 色彩空间中检测高饱和度绿色(微信绿按钮特征)
- 通过膨胀操作将刷新图标与"再玩一局"文字粘合为连通区域
- 识别到面积 > 100px² 的绿色区域 → 自动点击重开
| 项目 | 要求 |
|---|---|
| 操作系统 | Windows 10 / 11(64 位) |
| Python | 3.9 或更高版本 |
| 微信 | PC 版,需能正常运行"跳一跳"小游戏 |
| 显示器 | 建议 100% 缩放(高分屏需调整 DPI 设置) |
- 前往 Releases 页面
- 下载最新版
TytHelper.exe - 双击运行,无需安装任何依赖
# 1. 克隆仓库
git clone https://github.com/YSJohnson/Tyt-Helper.git
cd Tyt-Helper
# 2. (推荐)创建虚拟环境
python -m venv venv
venv\Scripts\activate
# 3. 安装依赖
pip install -r requirements.txt
# 4. 运行
python tyt_ui.py- 打开微信 PC 版
- 在聊天窗口或小程序面板中找到「跳一跳」并打开
- 确保游戏以独立窗口运行(点击小程序右上角"..." → "浮窗"或直接拖出独立窗口)
- 窗口标题必须为"跳一跳"(程序通过窗口标题定位游戏画面)
- 将游戏窗口保持在屏幕可见位置,不要最小化
启动 Tyt Helper 后,在界面中进行以下配置:
| 参数 | 位置 | 默认值 | 说明 |
|---|---|---|---|
| 游戏模式 | 左侧"游戏模式"卡片 | 单局模式 | 单局:跳完自动停止;无限:持续刷分 |
| 识别算法 | 左侧"识别算法"卡片 | 默认算法 | 根据实际表现切换 |
| 按压系数 | 底部栏 | 2.0 | 跳得太远 → 调小(1.95);太近 → 调大(2.05) |
| 跳跃间隔 | 底部栏 | 2.5s | 确保特殊跳台动画播放完毕,可以获得额外加分 |
点击绿色 启动 按钮,程序将自动:
- 找到"跳一跳"窗口
- 开始截取画面并识别
- 在右侧预览区域显示识别结果
- 自动执行跳跃
- 正常停止:点击"停止"按钮,程序会在当前跳跃完成后停止
- 紧急停止:将鼠标快速移至屏幕左上角(触发 pyautogui failsafe)
# 安装 PyInstaller
pip install pyinstaller
# 使用预置的 spec 文件打包
pyinstaller TytHelper.spec --noconfirm
# 打包产物位于 dist/TytHelper.exeTytHelper.spec 已预配置好 customtkinter 的资源收集和 --noconsole 模式,生成的是纯 GUI 应用(无命令行窗口)。
Tyt-Helper/
├── tyt_ui.py # 主程序入口,包含 GUI 界面、游戏循环、默认识别算法
│ ├── class JumpJumpApp # CustomTkinter 主窗口类
│ ├── class StdoutRedirector # 控制台输出重定向到 GUI 文本框
│ ├── self_detect() # 默认算法 - 棋子识别
│ ├── goal_detect() # 默认算法 - 目标识别
│ ├── jump() # 执行跳跃(模拟鼠标按压)
│ ├── check_and_click_restart() # 检测游戏结束并自动重开
│ └── get_window() # 通过窗口标题获取窗口句柄和位置
│
├── algo_java.py # Java 版移植算法
│ ├── tolerance_match() # RGB 颜色容差匹配
│ ├── java_self_detect() # 棋子识别(移植自 MyPosFinder)
│ ├── java_goal_detect() # 目标识别(移植自 NextCenterFinder)
│ ├── _white_point_find() # 白色中心点检测(移植自 WhitePointFinder)
│ └── _bottle_find() # 瓶子目标检测(移植自 BottleFinder)
│
├── images/
│ └── ui.png # UI 界面截图
│
├── TytHelper.spec # PyInstaller 打包配置
├── requirements.txt # Python 依赖清单
├── LICENSE # AGPLv3 许可证
├── .gitignore # Git 忽略规则
└── README.md # 本文件
| 常量 | 默认值 | 说明 |
|---|---|---|
WINDOW_TITLE |
"跳一跳" |
游戏窗口标题,用于窗口定位 |
PRESS_COEFFICIENT |
2.0 |
按压系数,像素距离 × 系数 = 按压毫秒数 |
MIN_PRESS_MS |
200 |
最小按压时长,防止无效短按 |
SCREEN_SIZE |
(612, 1151) |
算法处理分辨率(会先缩放到此尺寸) |
JUMP_INTERVAL_SEC |
2.5 |
跳跃间隔,确保动画播放和落点稳定 |
| 参数 | 值 | 说明 |
|---|---|---|
| 棋子目标 RGB | (40, 43, 86) |
Java 版棋子颜色特征 |
| 颜色容差 | 16 |
RGB 各通道 ± 容差范围内的像素视为匹配 |
| 白色中心点 RGB | (245, 245, 245) |
目标中心的白色圆点颜色 |
| 白色中心点尺寸 | 35~45 × 20~30 px |
有效的白色圆点尺寸范围 |
| BFS 搜索范围 | ±300px 水平, ±400px 垂直 |
洪水填充的最大搜索边界 |
Q: 提示"未找到名为 '跳一跳' 的独立窗口"?
A: 确保游戏窗口标题显示为"跳一跳",并且窗口没有被最小化。可以尝试关闭后重新打开游戏。
Q: 总是跳不准,要么太远要么太近?
A: 调整底部的"按压系数"参数。每次微调 0.01~0.03,观察 5 跳后再次调整。不同屏幕分辨率和 DPI 设置会影响最佳系数值。
Q: 无限模式下游戏结束但没有自动重开?
A: 确认游戏窗口没有被遮挡。程序通过检测画面中的绿色"再玩一局"按钮来触发重开,如果画面被其他窗口覆盖则无法识别。同时确保使用了最新版本的微信,按钮颜色可能有变化。
Q: 程序运行一段时间后识别率下降?
A: 可能是游戏窗口位置发生了偏移。检查窗口是否被意外移动。如果在无限模式下出现此问题,建议停止后重新启动。
Q: 高分屏(2K/4K)下识别不准?
A: 程序已通过 SetProcessDPIAware() 适配高分屏。如果仍不准,尝试在 Windows 显示设置中将缩放比例设为 100% 进行测试。
Q: 两种算法应该选哪个?
A: 推荐用默认算法。
- 仅支持 Windows 平台(依赖 win32gui、mss 等 Windows API)
- 需要游戏以独立窗口运行,不支持嵌入聊天窗口内的运行模式
- 游戏窗口不能被其他窗口遮挡
- 微信版本更新可能导致 UI 按钮颜色变化,影响重开检测
- 识别算法:Java 版 BFS 洪水填充算法移植自 burningcl/wechat_jump_hack,感谢原作者 chenliang(小红书团队)的开源贡献
本项目采用 GNU Affero General Public License v3.0 (AGPLv3)。
简单来说:你可以自由使用、修改和分发本项目,但任何修改版或衍生作品必须以相同的 AGPLv3 协议开源。即使是作为网络服务运行(SaaS),也必须向用户公开完整的源代码。
补充声明:本项目仅供学习交流使用,不得用于破坏游戏公平性或违反微信用户协议的行为。使用本软件所产生的任何后果由使用者自行承担。
