C++游戏自动化助手实战:图像识别+ADB控制实现明日方舟日常任务全自动

发布时间:2026/10/19 10:21:26
C++游戏自动化助手实战:图像识别+ADB控制实现明日方舟日常任务全自动 简介这是一份面向明日方舟玩家的自动化辅助工具源码基于C与图像识别技术实现日常任务的一键执行适合具备一定编程基础、希望研究计算机视觉在游戏场景落地的开发者参考。资源包共2000个文件约124.87MB以1487个json配置数据、190个h头文件、162个cpp源文件为主辅以hpp、py脚本、go与dart模块及少量md说明文档覆盖任务调度、战斗识别、基建生产、自动招募等核心逻辑。已有345人学习下载。读者可从中获取完整的图像预处理、特征提取与分类识别实现思路理解多线程并行处理大量图像数据的优化方式并参考任务触发、执行与结果验证的流程设计为自研自动化工具或视觉项目提供可复用的工程结构与排错经验。1. 明日方舟游戏助手用 C 和图像识别把日常任务压成一次点击凌晨两点我盯着模拟器里第 17 次重复的剿灭代理指挥突然意识到自己不是在玩游戏而是在给游戏打工。日常任务、基建换班、公开招募、肉鸽刷等级——这些操作本身没有难度纯粹是时间黑洞。后来接触到一类用 C 写的游戏助手核心思路很直接截屏、识别、模拟点击把整套日常流程串成一条自动化流水线。它适合两类人一类是想省下重复操作时间、把精力留给高难关卡的玩家另一类是想学图像识别落地、ADB 控制、多线程任务调度的 C 开发者。这份源码里能看到从AdbController.cpp到RoguelikeBattleTaskPlugin.cpp的完整链路不是玩具 Demo而是一个能跑起来的工程。2. 架构拆解从截屏到点击的完整链路2.1 分层设计识别层、决策层、执行层怎么切这个项目的代码组织方式很典型按职责切成三层。识别层负责把屏幕像素变成结构化数据代表文件是StageDropsImageAnalyzer.cpp和CombatRecordRecognitionTask.cpp决策层根据识别结果判断当前处于哪个界面、该执行什么动作TaskData.cpp和AutoRecruitTask.cpp属于这一层执行层通过AdbController.cpp把点击、滑动指令下发到设备。三层之间用任务对象传递状态而不是互相直接调用这样加新任务时只需要写一个新的 Task 类不用动识别和执行代码。我一般会把这种结构理解成一条流水线摄像头截屏→ 质检员识别→ 调度员决策→ 机械臂ADB。每个环节只关心自己的输入输出出问题时也容易定位——识别错了就看图像处理点歪了就看 ADB 坐标换算。2.2 核心文件职责表文件职责关键依赖main.cpp程序入口初始化任务队列和主循环任务调度器AdbController.cpp封装 ADB 连接、截屏、点击、滑动ADB 可执行文件TaskData.cpp定义任务数据结构与状态机无AutoRecruitTask.cpp公开招募的标签识别与选择逻辑图像识别模块RoguelikeBattleTaskPlugin.cpp肉鸽模式战斗决策与干员部署识别 决策InfrastProductionTask.cpp基建换班、生产设施管理图像识别 点击StageDropsImageAnalyzer.cpp关卡掉落物识别OpenCVCombatRecordRecognitionTask.cpp战斗记录识别与回放分析OpenCVdart_api_dl.c/callback.c跨语言接口与回调桥接Dart FFI这张表不是让你背而是让你在改代码时知道该翻哪个文件。比如想加一个“自动刷活动图”的功能入口在main.cpp注册任务识别逻辑参考StageDropsImageAnalyzer.cpp点击部分复用AdbController.cpp。2.3 图像识别流水线预处理到模板匹配识别部分的核心流程在StageDropsImageAnalyzer.cpp里体现得比较完整。典型步骤是截屏得到原始图像 → 灰度化 → 二值化或边缘检测 → 在目标区域做模板匹配或特征比对 → 输出识别结果。下面这段代码模拟了从截屏到匹配的骨架实际项目里会拆到不同函数中。// 伪代码示意从截屏到模板匹配的识别流程 cv::Mat screenshot adbController-captureScreen(); // 获取原始截图 cv::Mat gray; cv::cvtColor(screenshot, gray, cv::COLOR_BGR2GRAY); // 灰度化减少计算量 // 对感兴趣区域做裁剪避免全图匹配拖慢速度 cv::Rect roi(100, 200, 300, 150); cv::Mat roiImage gray(roi); cv::Mat templ cv::imread(templates/stage_clear.png, cv::IMREAD_GRAYSCALE); cv::Mat result; cv::matchTemplate(roiImage, templ, result, cv::TM_CCOEFF_NORMED); // 归一化相关系数匹配 double minVal, maxVal; cv::Point minLoc, maxLoc; cv::minMaxLoc(result, minVal, maxVal, minLoc, maxLoc); if (maxVal 0.85) { // 阈值根据实际测试调整 // 匹配成功执行下一步动作 adbController-tap(roi.x maxLoc.x templ.cols / 2, roi.y maxLoc.y templ.rows / 2); }逻辑说明灰度化是为了降低计算量ROI 裁剪是为了缩小搜索范围matchTemplate用归一化相关系数法对光照变化有一定容忍度。阈值 0.85 不是固定的不同分辨率下需要重新标定。参数方面roi的坐标和大小取决于游戏 UI 布局换模拟器分辨率后必须同步调整否则识别率会断崖式下跌。2.4 ADB 控制层点击坐标怎么算才不飘AdbController.cpp负责和设备通信。常见做法是通过adb shell input tap x y发送点击通过adb exec-out screencap -p获取截图。难点在于坐标换算截图分辨率、模拟器窗口分辨率、游戏内渲染分辨率三者可能不一致直接拿识别到的像素坐标去点击大概率点偏。// 坐标换算示意把截图坐标映射到 ADB 点击坐标 struct Resolution { int width; int height; }; Resolution screenRes {1920, 1080}; // 截图分辨率 Resolution adbRes {1280, 720}; // ADB 实际控制分辨率 void tapWithScale(int x, int y) { int adbX x * adbRes.width / screenRes.width; int adbY y * adbRes.height / screenRes.height; std::string cmd adb shell input tap std::to_string(adbX) std::to_string(adbY); system(cmd.c_str()); }这段代码的关键是比例映射。实际项目里还会处理横竖屏切换、状态栏偏移、模拟器边框等问题。我踩过的坑是截图是 1920×1080但 ADB 控制区域只有 1280×720没做换算时点击全部偏移到右下角任务直接卡死。后来每次换模拟器都先跑一遍坐标校准确认点击位置和识别位置对齐再继续。3. 跑起来编译、连接与任务配置3.1 环境准备与依赖安装这个项目是 C 工程依赖 OpenCV 做图像处理依赖 ADB 做设备控制。在 Windows 上我一般用 vcpkg 装 OpenCV在 Linux 上用 apt 装libopencv-dev。ADB 需要单独下载 platform-tools确保adb devices能列出模拟器或真机。# Ubuntu 下安装依赖 sudo apt update sudo apt install -y build-essential cmake libopencv-dev adb # 确认 ADB 能识别设备 adb devices # 输出应包含类似127.0.0.1:5555 deviceWindows 下如果用 Visual Studio需要在项目属性里配置 OpenCV 的 include 和 lib 路径。常见做法是把 OpenCV 的build\x64\vc16\bin加到系统 PATH否则运行时会报找不到opencv_world4xx.dll。3.2 编译工程与首次运行项目里如果有CMakeLists.txt直接走 CMake 流程如果是 VS 工程用.sln打开编译。编译前确认dart_api_dl.c和callback.c的链接设置正确这两个文件涉及跨语言回调漏掉会报符号未定义。mkdir build cd build cmake .. cmake --build . --config Release编译产物一般在build/Release/或build/下。首次运行前把模板图片目录放到可执行文件同级路径否则识别模块读不到模板会直接返回失败。运行后程序会尝试连接 ADB 设备连接成功后开始执行任务队列。注意模拟器建议用 1280×720 或 1920×1080 分辨率开启 ADB 调试关闭游戏内的“高性能模式”以减少渲染差异。3.3 任务配置从日常到肉鸽怎么选任务配置通常通过配置文件或命令行参数控制。TaskData.cpp里定义了任务类型和参数结构main.cpp根据配置决定启动哪些任务。常见配置项包括是否自动公开招募、基建换班间隔、肉鸽模式是否启用、战斗是否代理指挥等。// 任务配置结构示意 struct TaskConfig { bool autoRecruit true; // 自动公开招募 bool infrastUpdate true; // 基建换班 bool roguelike false; // 肉鸽模式默认关闭 int battleCount 0; // 战斗次数0 表示不限制 int recruitInterval 4; // 招募检查间隔小时 };参数说明roguelike默认关闭是因为肉鸽决策复杂、耗时较长新手建议先跑通日常再开。recruitInterval控制公开招募的检查频率设太短会频繁截屏增加 CPU 占用设太长会错过刷新。我一般设 4 小时和游戏内招募刷新节奏对齐。4. 避坑排查识别飘、点击偏、任务卡死怎么修4.1 识别率突然下降现象昨天还能正常识别关卡结算界面今天一直匹配失败。原因通常是游戏 UI 更新、模拟器分辨率变化、或者模板图片被误删。解决先确认模拟器分辨率没变再检查模板目录是否完整最后用截图工具手动截一张当前界面和模板做对比看差异在哪。如果 UI 确实改了需要重新截取模板并调整 ROI 坐标。4.2 点击位置偏移现象识别到了按钮但点击没反应或点到别的地方。原因多半是坐标换算没做或者 ADB 控制分辨率和截图分辨率不一致。解决在AdbController.cpp里加日志打印识别坐标和实际点击坐标对比两者差异。如果差异是固定比例补上换算如果差异随机检查是否有状态栏或导航栏干扰。4.3 任务执行到一半卡死现象程序运行几分钟后不再有任何操作日志停在某个任务。原因可能是识别进入死循环、ADB 连接断开、或者某个弹窗遮挡了预期界面。解决给每个任务加超时机制超过设定时间未完成就跳过或重启任务。同时在主循环里定期检查 ADB 连接状态断线后自动重连。// 任务超时保护示意 auto start std::chrono::steady_clock::now(); while (!taskFinished) { auto now std::chrono::steady_clock::now(); auto elapsed std::chrono::duration_caststd::chrono::seconds(now - start).count(); if (elapsed 120) { // 单任务超过 120 秒强制退出 log(Task timeout, skipping...); break; } // 正常任务逻辑 }4.4 多线程下的资源竞争现象开启多个任务并行后程序偶尔崩溃或识别结果错乱。原因是多个线程同时访问 ADB 连接或共享图像缓冲区。解决给 ADB 操作加互斥锁确保同一时间只有一个线程在截屏或点击。图像缓冲区每个线程独立分配不要复用全局 Mat 对象。4.5 模拟器兼容性问题现象在某个模拟器上正常换一个就完全跑不起来。原因是不同模拟器的 ADB 端口、截图命令、渲染方式有差异。解决优先用项目文档推荐的模拟器确认 ADB 端口正确常见 5555、62001、7555截图命令用adb exec-out screencap -p而不是adb shell screencap后者在某些模拟器上会返回空数据。5. 二次开发加一个新任务模块的完整思路想给这个助手加一个“自动刷活动图”的功能不需要重写整个工程按现有架构扩展就行。第一步在TaskData.cpp里定义新任务类型和参数结构比如ActivityStageTask包含关卡编号、刷取次数、是否使用理智药。第二步参考StageDropsImageAnalyzer.cpp写活动图结算界面的识别逻辑重点是 ROI 坐标和模板图片要针对活动 UI 重新标定。第三步在main.cpp的任务注册处把新任务加进队列配置好触发条件。改造时有一个技巧先用现有任务的识别和点击代码跑通流程再替换成活动图专用的识别模板。不要一上来就写全新逻辑那样出问题很难判断是识别错了还是决策错了。我一般会保留一个“调试模式”开启后每一步识别结果和点击坐标都输出到日志方便对照截图排查。验证方法也很直接手动打一次活动图截取关键界面进入关卡、结算、掉落用这些截图跑识别模块看匹配率是否达标。达标后再接入自动流程设置刷取次数为 1观察完整链路是否跑通。确认无误后再放开次数限制。改造步骤涉及文件验证方式定义任务结构TaskData.cpp编译通过配置能读取编写识别逻辑新建ActivityStageAnalyzer.cpp用截图测试匹配率注册任务入口main.cpp任务队列能启动新任务接入点击执行AdbController.cpp观察点击位置是否准确加超时与重试任务主循环模拟卡死场景验证从那以后我每次加新任务都强制先跑一遍“单次执行 全日志”模式确认识别和点击都对得上再开自动循环。这个习惯帮我省了很多半夜起来看模拟器卡在哪的麻烦。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询