扒一扒明日方舟自动化工具 MAA:图像识别是怎么认出游戏界面的
【免费下载链接】MaaAssistantArknights《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supporting all clients.项目地址: https://gitcode.com/GitHub_Trending/ma/MaaAssistantArknights
每天早上的日常——唤醒、自动公招、基建换班、扫荡作战、领邮件,手动做完至少要四十分钟。MaaAssistantArknights(下称 MAA)是一款明日方舟自动化工具,把这四十分钟压缩成一次点击:它定时截取游戏画面,认出当前停在哪个界面,再点对应的位置。这篇文章把源码翻了一遍,重点讲清楚这类工具的两个核心问题:它怎么"看懂"屏幕,又怎么把看懂的结果变成一次真实的点击。
🔧 MAA 怎么跑起来:从 clone 到一键长草
想最快看到效果,走命令行这条线最直接。克隆仓库git clone https://gitcode.com/GitHub_Trending/ma/MaaAssistantArknights,构建用 CMake Presets 管理,Windows 下直接选 Visual Studio 预设,Linux 下是 Ninja。装好之后,整个工作流就几条命令:maa install安装 MaaCore 核心和资源包,maa init交互式填写模拟器地址和客户端类型,然后maa startup把游戏拉进主界面,maa fight 1-7自动打完指定关卡。第一遍跑完,终端里会刷出一串识别日志,模拟器上的角色自己点完了所有按钮——这就是后面要拆的那套东西在干活。本节就当一份极简的 MAA 使用教程,GUI 版本的流程与之等价:连上模拟器,勾选要跑的日常,点开始。
这张图是 MAA 的主界面:左侧是任务链勾选(唤醒、公招、换班、理智作战……),中间是候选关卡和资源阈值设置,右侧日志里每一行都是一次公招 OCR 的结果。
日志值得多看一眼:"公招识别结果:近卫干员 医疗干员 近战位 治疗 群攻"——这是从像素里逐字读出来的,不是游戏把数据递给程序的。
🖥️ 机制拆解:一张截图走完"看图、定位、点击"
MAA 的主循环朴素得几乎有点反高潮:截一张图,判断现在是什么界面,是预期界面就点,不是就等一会儿再截。所有学问都在第二步里。
输入是一张截图。处理这一层的是 Vision 模块里的一组识别器,每个负责回答一类问题:Matcher做模板匹配,拿预制的"开始行动"按钮小图在截图上逐像素滑动比对,命中就给出中心坐标;OCRer跑一个 ONNX 模型(微软开源的推理运行时,加载训练好的神经网络做推理)识别文字,读出关卡编号、仓库里的材料数量;FeatureMatcher用特征点匹配,在模板容易失手的复杂场景里补位。输出统一收敛成"语义信息 + 坐标",交给任务层消费。这套流程就是游戏图像识别自动化的标准打法:不关心游戏内部是什么,只关心屏幕上出现了什么。
官方文档里的模板匹配示例:只要"开始行动"按钮出现在画面里,无论皮肤配色怎么变,模板都能匹配上——这是 MAA 识别能力的底层依据。
任务层的每个任务继承自AbstractTask,run()方法本质是个带重试的循环:_run()失败就睡task_delay再试,实在不行交给on_run_fails()决定是回主界面恢复还是放弃报错。单个任务又能拆成若干插件,靠register_plugin()把"选干员""点确认弹窗"这类小动作挂进去。关键在于,任务链的编排顺序和每个任务的参数全部来自 JSON 配置而不是代码——游戏版本更新改了界面时,典型修法是换掉资源包里的某张小图或改一条配置,核心不用重新编译。
工程取舍:C++、图像识别和三层 Controller
从目录结构就能看出 MAA 是"一个核心、多个壳":C++20 写的 MaaCore 干所有实事,上面套 WPF GUI(Windows)、macOS GUI、命令行,外加一排语言绑定。有三个取舍值得掰扯。
为什么是 C++ 而不是 Python。游戏自动化工具每秒都在处理图像:解码、匹配、模型推理,Python 的 GIL 和内存模型扛不住多实例长跑;更实际的是,C++ 能编译成单一核心库,Python、Java、Rust、Go、Dart 的绑定都只是对 C 接口的封装。如果核心用 Python 写,Dart 里那套完整的 Flutter 嵌入方案基本不成立。
为什么走图像识别而不是读内存或注入。读内存快且准,但游戏反作弊直接能检测,而且官服、B 服、Yostar 海外服各家的内存布局都不同。图像识别把游戏当纯黑盒:程序只做"看屏幕"和"点按钮"两件事,操作路径跟人一模一样,一套代码跨所有客户端通吃。代价是脆弱——UI 一改、弹窗一挡、DPI 一缩放都可能失手,所以上面那套重试循环和资源热更新机制才必须存在。
为什么 Controller 单独抽一层。"点击坐标 (x, y)" 有三种实现:AdbController走 ADB 通道连模拟器和真机,Win32Controller操作本地窗口,MinitouchController用注入式触摸驱动。任务代码不关心底下是哪一种,换设备只改一个连接参数。
二次开发与集成路径
想基于 MAA 做点自己的东西,入口有三类。
- 新任务:继承
AbstractTaskPlugin再注册进任务;任务链编排由 JSON 定义,插件机制看 src/MaaCore/Task/,配置格式参考 docs/maa_tasks_schema.json - 语言集成:C 接口在 include/MaaCore.h,
src/下的 Python、Java、Rust、Golang、Dart 绑定全是它的薄封装 - 识别与控制扩展:新识别器加在 src/MaaCore/Vision/,新控制后端加在 src/MaaCore/Controller/
另外src/Golang/里带了一个 HTTP 服务,把 MAA 挂到无头服务器上、用 REST 请求触发日常,是社区搭定时任务最常见的姿势。
局限与适用边界
说实话,MAA 只服务明日方舟这一个游戏,想换到别的游戏,模板图和任务配置要全部重做,基本等于重做半个项目。游戏大改 UI 的过渡期识别会失效,得等资源包更新或者自己动手补模板。还有合规和账号风险问题,图像识别虽然非侵入,但"非侵入"不等于"零风险",用之前自己掂量。
结语
想做自己游戏自动化的,重点看 Vision 加 Controller 的分层,这套"识别器与设备后端解耦"的拆法可以直接搬走;想学带重试和插件机制的状态机怎么设计的,把AbstractTask.cpp通读一遍,篇幅不长但每个分支都有讲究;只想躺平的,装个 release 版本点下开始,每天省下的四十分钟就是净赚。
【免费下载链接】MaaAssistantArknights《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supporting all clients.项目地址: https://gitcode.com/GitHub_Trending/ma/MaaAssistantArknights
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考