从零实现《三角洲行动》手游自动跑刀脚本:ADB 直控 + OpenCV 视觉识别 + 固定点位搜刮)三角洲自动跑刀教程

从零实现《三角洲行动》手游自动跑刀脚本:ADB 直控 + OpenCV 视觉识别 + 固定点位搜刮

从零实现《三角洲行动》手游自动跑刀脚本:ADB 直控 + OpenCV 视觉识别 + 固定点位搜刮

声明 :本文仅用于分享 Android 自动化与计算机视觉的工程实践,所有内容面向技术学习。竞技游戏的用户协议通常禁止第三方自动化工具,请勿用于线上对局。Demo 与思路仅供研究,后果自负。


先看看效果:

三角洲

https://www.bilibili.com/video/BV1AP7X6AEfh/?spm_id_from=333.1387.homepage.video_card.click

视频效果

一、前言

很多人见过 B 站、CSDN 上的"自动跑刀"脚本------进图后自动跑到几个固定点位搜刮物资。这类脚本到底怎么实现?本文以《三角洲行动》手游为例,完整复盘一套**「电脑 ADB 直控真机 + OpenCV 视觉识别 + 固定路线」**的实现方案,重点讲清楚四个工程难点:

  1. 怎么控制手机(截图 / 点击 / 滑动)
  2. 怎么判断"真进游戏了"(霍夫圆检测小地图)
  3. 怎么识别"这把刷在哪个出生点"(小地图模板匹配)
  4. 怎么自动拾取物资(物资标签检测)

以及一个绕不开的结论:为什么"固定点位"方案可行,而"自主智能跑图"不可行。


二、整体架构与技术栈

复制代码
PC (Python)
 ├─ ADB 控制层      ------ 截图 / input tap / input swipe
 ├─ 视觉识别层(OpenCV)
 │    ├─ 霍夫圆检测   ------ 检测小地图 → 判定是否进图
 │    ├─ 模板匹配     ------ 小地图比对 → 识别出生点
 │    └─ 区域裁剪/遮罩 ------ 物资标签、按钮定位
 └─ 决策/路线层      ------ 每个出生点一条固定动作序列
        ↓ ADB
   Android 真机 / 模拟器

技术栈

模块 技术
设备控制 ADB(platform-tools)input tap/swipeexec-out screencap
图像处理 OpenCV-Python(HoughCirclesmatchTemplate、掩膜)
数值计算 NumPy
语言 Python 3.10

关键前提 :MIUI / HyperOS 等系统默认禁用 ADB 模拟点击(INJECT_EVENTS 权限),需在开发者选项中开启**「USB 调试(安全设置)」**(需插 SIM 卡 + 登录账号)。开启后 adb shell input tap/swipe 才可用,这是整套方案的基础。


三、ADB 控制层:截图、点击、滑动

一切的基础是「能截屏、能操作」。用 subprocess 包一层 ADB:

python 复制代码
import subprocess, time
import numpy as np
import cv2

ADB = r"D:\platform-tools\adb.exe"
SERIAL = "你的设备序列号"   # adb devices 查看

def adb(*args, binary=False, timeout=20):
    cmd = [ADB, "-s", SERIAL] + list(args)
    r = subprocess.run(cmd, capture_output=True, timeout=timeout)
    return r.stdout if binary else r.stdout.decode("utf-8", "ignore")

def screenshot():
    """exec-out screencap 直接拿二进制 PNG,OpenCV 解码,无需落盘。"""
    raw = adb("exec-out", "screencap", "-p", binary=True)
    return cv2.imdecode(np.frombuffer(raw, np.uint8), cv2.IMREAD_COLOR)

def tap(x, y, wait=1.2):
    adb("shell", "input", "tap", str(x), str(y))
    time.sleep(wait)

def swipe(x1, y1, x2, y2, dur_ms=300):
    adb("shell", "input", "swipe", str(x1), str(y1), str(x2), str(y2), str(dur_ms))

对局内的"走位"和"转视角",本质也是 swipe:

  • 走位 = 在左手虚拟摇杆上按住拖动一段时间(swipe 的 duration 就是按住时长)。注意摇杆死区大,必须大幅度推满才会走:
python 复制代码
def move_forward(seconds):
    # 摇杆中心(430,760),向上推满 → 前进
    swipe(430, 780, 430, 350, int(seconds * 1000))

def look_right_90():
    # 右侧视角区横向滑动,约 480px ≈ 转 90°
    swipe(1700, 500, 2180, 500, 350)

横屏分辨率 2400×1080 下,这些坐标都是实测标定出来的。


四、核心难点一:怎么判断"真进游戏了"?

这是最坑的一步。游戏从「点击出发」到「真正进图」要经历:匹配 → 选干员 → 着陆确认 → 加载(约30s)→ 进图 。早期我用"固定等 30 秒"或"识别匹配界面文字",都不稳------匹配时间不固定,加载界面文字时有时无,经常还没进游戏就开始乱跑刀

突破口:对局内左上角有个圆形小地图,而菜单/加载界面没有。 于是用霍夫圆检测(HoughCircles) :检测到小地图圆 = 真进游戏。

python 复制代码
def detect_minimap_circle(screen=None):
    """检测左上角小地图圆,返回 (cx,cy,r) 或 None。"""
    if screen is None:
        screen = screenshot()
    roi = screen[0:460, 0:500]                       # 只在左上角找,提速
    g = cv2.medianBlur(cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY), 5)
    cs = cv2.HoughCircles(g, cv2.HOUGH_GRADIENT, dp=1, minDist=300,
                          param1=100, param2=40, minRadius=140, maxRadius=215)
    if cs is None:
        return None
    c = cs[0][0]
    return (int(c[0]), int(c[1]), int(c[2]))

def is_in_game(screen=None):
    return detect_minimap_circle(screen) is not None

实测圆心稳定在 (~277, 210)、半径 ~145,几乎每把一致。is_in_game() 就是可靠的"进图判定",彻底解决了时序错位问题。


五、核心难点二:识别"这把刷在哪个出生点"

关键前提 :很多人以为出生点随机,其实不少撤离类地图的出生点就那固定的几个 。这意味着------只要识别出本把刷在哪个出生点,就能跑预先调好的对应路线。这正是"固定点位脚本"成立的根基。

识别靠小地图 :它是北朝上 + 玩家居中 的,所以同一个出生点,周围地形布局每次都一样,非常适合模板匹配

5.1 用圆检测把小地图"圆形抠出来"

直接方形裁剪会带进会变化的世界背景(四个角),干扰匹配。更好的做法是:圆检测定位 → 圆形掩膜把圆外涂黑 → 归一化尺寸

python 复制代码
def get_minimap(screen=None):
    """抠出圆形小地图(圆外涂黑),归一化 360x360。"""
    if screen is None:
        screen = screenshot()
    circ = detect_minimap_circle(screen)
    if circ is None:
        return None
    cx, cy, r = circ
    r = min(r + 8, cx, cy)
    crop = screen[cy - r:cy + r, cx - r:cx + r].copy()
    mask = np.zeros(crop.shape[:2], np.uint8)
    cv2.circle(mask, (crop.shape[1] // 2, crop.shape[0] // 2), r, 255, -1)
    crop = cv2.bitwise_and(crop, crop, mask=mask)        # 圆外涂黑
    return cv2.resize(crop, (360, 360))

配图:圆检测 + 掩膜后抠出的干净圆形小地图。

有些出生点小地图上直接带地名(如"军营""帐篷区"),还能用 OCR 读字辅助判断:

5.2 模板匹配识别出生点

提前在每个出生点出生瞬间 采集一张圆形小地图存为模板(spawn1.pngspawn2.png...),进图后拿当前小地图逐一比对,取最高分:

python 复制代码
import os
def detect_spawn(screen=None, threshold=0.6):
    mm = get_minimap(screen)
    if mm is None:
        return None
    best = None
    for f in os.listdir("templates/spawns"):
        tpl = cv2.imread(os.path.join("templates/spawns", f))
        if tpl is None or tpl.shape != mm.shape:
            continue
        res = cv2.matchTemplate(mm, tpl, cv2.TM_CCOEFF_NORMED)
        _, maxv, _, _ = cv2.minMaxLoc(res)
        if best is None or maxv > best[1]:
            best = (os.path.splitext(f)[0], float(maxv))
    return best if best and best[1] >= threshold else None

采集规范(踩坑经验) :模板必须统一风格 才匹配得准------① 都在出生瞬间、未移动时采集(玩家居中、初始朝向);② 统一用"圆检测 + 掩膜 + resize 360×360";③ 小地图上的玩家箭头、队友标记、区域线是动态噪声,进阶可把中心圆区再挖掉,只比静态地形。


六、核心难点三:自动拾取物资

走到物资点后,画面右上方会弹出物资标签 (如"9V电池")。坑点:拾取不是点屏幕固定的"交互键",而是点这个标签本身。

python 复制代码
PICKUP_LABEL = (1600, 280)   # 右上角物资标签位置(横屏)

def pickup():
    tap(*PICKUP_LABEL, wait=0.6)

点中后画面提示"已拾取 XX 到保险箱",即成功。

进阶可用模板匹配/颜色检测先判断"标签框是否存在",存在再点,避免空点。


七、把它串起来:固定路线

每个出生点配一条固定动作序列,识别到哪个出生点就跑哪条:

python 复制代码
ROUTES = {
    # 降落点:出生 → 前进2秒 → 右转90° → 点标签拾取
    "spawn2": [("forward", 2), ("look", 480, 0), ("pickup",)],
    # 其它出生点继续补......
}

def run_route(name):
    for step in ROUTES.get(name, []):
        if step[0] == "forward":
            move_forward(step[1])
        elif step[0] == "look":
            swipe(1700, 500, 1700 + step[1], 500, 350)
        elif step[0] == "pickup":
            pickup()

主循环:

python 复制代码
def main_loop():
    deploy()                        # 自动点出发/指挥出战进局
    if not wait_in_game(timeout=60):# 圆检测等进图
        return
    spawn = detect_spawn()          # 识别出生点
    if spawn:
        run_route(spawn[0])         # 跑对应固定路线
    extract()                       # 撤离/自杀
    back_to_lobby()                 # 退出结算 → 回大厅

八、一个诚实的工程结论

做下来最大的体会:"识别"不难,"导航"才难。

  • 能做到:CV 识别进图、识别出生点、识别物资标签;固定出生点 + 固定路线 + 自动进局/撤离/循环。
  • 做不到(靠脚本盲操作) :像人一样"自主跑图、避开墙和障碍、找到好货"。3D 场景里盲走 ADB 反复撞墙撞围栏,这需要深度感知 + 路径规划(等于游戏 AI 自主导航),是另一个数量级的工程;而真正的"自动打人"= 目标检测自瞄 = 顶格外挂,必被反作弊封号。

所以"固定点位"方案之所以流行,正是因为它用确定性(固定出生点+固定路线)绕开了最难的自主导航------这是工程上的务实取舍。


九、总结

难点 解法
控制手机 ADB input tap/swipe + screencap
进图判定 霍夫圆检测小地图 is_in_game()
出生点识别 圆形小地图掩膜 + matchTemplate
物资拾取 点右上角物资标签
智能跑图 ❌ 用"固定出生点+固定路线"务实绕开

整套方案把 Android 自动化OpenCV 模板匹配 / 霍夫圆检测 结合起来,是一个很好的"CV + 自动化"工程练习。

再次提醒:仅供学习计算机视觉与自动化技术,切勿用于线上竞技对局

源码链接:


如果这篇对你有帮助,欢迎点赞收藏。技术交流,理性使用。

相关推荐
YOLO数据集集合1 小时前
YOLOv11+DeepSeek多技术融合电网缺陷巡检平台|绝缘子破损瓷瓶故障AI识别、前后端一体化电力运维管理系统落地开发
运维·人工智能·yolo
txh05071 小时前
从零开始学习FOC
单片机·嵌入式硬件·学习
2601_961194021 小时前
考研政治历年真题及解析pdf
stm32·单片机·嵌入式硬件·物联网·考研·pdf
今日待办1 小时前
STM32H747I-DISCO 开发指南【数字麦克风使用】
stm32·单片机·嵌入式硬件
赛博云推-Twitter热门霸屏工具1 小时前
Twitter自动发推工具怎么选?从人工运营到自动化管理的实践分析
运维·自动化·twitter
YOLO数据集集合1 小时前
无人机航拍+深度学习落地智慧农业:作物出苗率目标检测开源数据集工程详解|YOLO作物计数、田间苗期AI监测、农情数字化训练资源
人工智能·深度学习·yolo·目标检测·计算机视觉·无人机
世微 如初2 小时前
【方案】AP5127摩托车灯驱动设计:12-100V输入,2.5A恒流
单片机·嵌入式硬件
嵌入式ZYXC2 小时前
第7章:原理图设计与阅读——从“能看懂”到“会画”的关键一跃
stm32·单片机·嵌入式硬件·物联网
紧固件研究社2 小时前
紧固件模具去哪选?2026上海紧固件展汇集全品类模具厂家
自动化·制造·紧固件