• 明日方舟脚本1.0(pythonadbcv2)


    一、目的

    《Python从入门到实践》第14章拉拉杂杂“抄”完,急于练手,便捡起以前一直想写却没写完的“鼠标键盘模拟”程序。

     

    二、思考

    图1.0 auto_game思考方向

    如图1.0,思考了两种实现方法。

    第一种方法是在电脑层面模拟电脑鼠标点击。使用pyautogui库实现之后,MUMU模拟器内运行游戏并未做出相应反应。更换20180111版本MUMU,仍然不成功。如果仍想采用这种思路,就需要更换模拟器软件,或者采用驱动级鼠标键盘模拟。

    第二种方法通过adb(Android Debug Bridge)操作管理andriod设备。下面对第二种方法予以讨论。

     

    (一)模拟过程

    如图1.1所示,明日方舟1-7刷图可以分为三个部分:开始(①、②)、等待(③)、结束(④)。

    图1.1 1-7刷图过程

     

    1.开始阶段(①、②)

    需要在两个特定位置(“开始行动”)点击两次。

    2.等待阶段(③)

    需要等待一段时间。

    3.结束阶段(④)

    需要在除“获得物品”之外的其他地方点击一次。

     

    (二)实现思路

    1.判断当前游戏阶段

    使用adb命令截图,cv2判断特定图形出现在截图中的可能性,超过阈值,即为出现特定场景。

    2.特定场景时发出点击命令

    3.点击位置伪随机

    4.点击时间间隔伪随机

    5.特殊情况

    开始阶段的①、②两图需要点击的按钮范围存在重合部分。可以将两次独立的判断后点击合并为:判断出现场景①后,点击两次。

    结束阶段的④图,只需要在屏幕的上半部分点击一次即可。

     

    三、实现过程

    (一)安装cv2

    图2.0 opencv-python安装过程

    安装cv2实际上是安装opencv-python。不推荐使用pip指令安装,因为那样下载速度感人。建议图2.0所示,先去下好whl包,本地安装。

    (下载地址:https://pypi.org/project/numpy/     https://pypi.org/project/opencv-python/ )

     

    (二)连接安卓设备

    本文使用MUMU版本为:2.3.4(0327192208)

    1.找到adb

    图2.1 adb_server

    如图2.1,MUMU模拟器默认的adb位置为:MuMuemulator emuvmonitorin

    2.修改环境变量

    图2.2 打开环境变量

    >此电脑>属性>高级系统设置>环境变量,双击Path更改:添加进adb_server所在的文件路径。

     

    3.连接

    对于windows系统,MUMU默认的连接端口为:127.0.0.1:7555

    在命令行窗口输入指令:>adb_server connect 127.0.0.1:7555

    图2.3 连接成功

    (三)编写程序

     1.框架

    图3.0 auto_game框架

    如图3.0 所示,程序分为4部分:setting(包含Settings对象)、robot_functions(包含一些操作函数)、robot(包含Robot对象)、main(主函数auto_game)。

    2.setting.py

     1 import cv2
     2 class Settinigs:
     3     """表示机器人参数设置的类"""
     4     def __init__(self):
     5         #机器人玩游戏局数
     6         self.num = 30
     7         #机器人可点击屏幕区域范围
     8         self.clickx = [830,935]
     9         self.clicky = [500,515]
    10         self.t_start = cv2.imread("./pictures/t_start.png")
    11         self.t_end = cv2.imread("./pictures/t_end.png")

     3.robot_functions.py

     1 import os
     2 import cv2
     3 import time
     4 import random
     5 
     6 
     7 def execute(cmd):
     8     #构造并执行adb命令
     9     str = "adb_server shell  {cmdStr}".format(cmdStr=cmd)
    10     # print(str)
    11     os.system(str)
    12 
    13 def click(x, y):
    14     #点击像素点
    15     click_order = 'input tap {} {}'.format(x, y)
    16     execute(click_order)
    17 
    18 def get_randpoint(x,y):
    19     px = random.randint(x[0], x[1])
    20     py = random.randint(y[0], y[1])
    21     return px,py
    22 
    23 def sleep_randtime(min,max):
    24     time.sleep(random.uniform(min,max))
    25 
    26 def match(img,template):
    27     """计算图像中包含模板的最大可能性,取值范围0~1"""
    28     res = cv2.matchTemplate(img,template,cv2.TM_CCOEFF_NORMED)
    29     return res.max()
    30 
    31 def shot_screen(img_name):
    32     """截屏并命名为img_name,返回图片"""
    33     shot_order = "screencap -p /storage/emulated/0/Pictures/{name}.png".format(name = img_name)
    34     execute(shot_order)
    35     poll_order ="adb_server pull /storage/emulated/0/Pictures/{name}.png ./pictures/{name}.png".format(name = img_name)
    36     #因为拉取命令格式特殊,直接用os
    37     os.system(poll_order)
    38     res = cv2.imread("./pictures/{name}.png".format(name = img_name))
    39     return res
    40 
    41 def shot_match(img_name,template):
    42     #截屏命名为img_name,img_name与template匹配,成功返回True,失败返回False
    43     n = 0
    44     while n < 15:
    45         img1 = shot_screen(img_name)
    46         res = match(img1, template)
    47         if res > 0.97:
    48             print("-Matched {} times.".format(n+1))
    49             return True
    50         else:
    51             sleep_randtime(0.8, 1.2)
    52         n += 1
    53     print("-Match failed.")
    54     return False

    4.robot.py

     1 import robot_functions as rf
     2 
     3 
     4 class Robot():
     5     def __init__(self,settings):
     6         self.settings = settings
     7 
     8     def start(self):
     9         #截屏并匹配
    10         rf.shot_match("img1",self.settings.t_start)
    11         #延时点击区域内随机点两次
    12         x,y = rf.get_randpoint(self.settings.clickx,self.settings.clicky)
    13         rf.click(x,y)
    14         rf.sleep_randtime(0.8,1.5)
    15         rf.click(x, y)
    16 
    17     def waiting(self):
    18         print("-Waiting......")
    19         rf.sleep_randtime(79.0,81.0)
    20 
    21     def end(self):
    22         #截屏并匹配
    23         if not rf.shot_match("img2",self.settings.t_end):
    24             print("Game over.")
    25             return False
    26         x, y = rf.get_randpoint([0,1023],[0,250])
    27         rf.click(x, y)
    28         rf.sleep_randtime(1.8, 2.0)
    29         return True

    5.auto_game.py

     1 from robot import Robot
     2 from settings import Settinigs
     3 
     4 
     5 settings = Settinigs()
     6 n = 0
     7 for n in range(settings.num):
     8     robot = Robot(settings)
     9     robot.start()
    10     robot.waiting()
    11     if not robot.end():
    12         break
    13 
    14 print("Done {} times.".format(n+1))
    15 print("Consumed {} sanity.".format((n+1)*6))

    注:本博客仅供学习交流,严禁其他非法用途。

     

    1.MUMU开发者必备说明书:http://mumu.163.com/help/func/20190129/30131_797867.html

  • 相关阅读:
    web开发中禁止因为网速慢导致重复提交数据
    margin四个元素的顺序
    js阻止提交表单(post)
    js中DOM集合的动态特性
    js正则表达式中=s.g表示什么意思
    js去掉字符串前后空格的五种方法
    电脑结构和CPU、内存、硬盘三者之间的关系
    mysql——查询练习
    python基础知识14——I/O阻塞非阻塞,同步异步
    Redis主从数据库的安装及主从配置
  • 原文地址:https://www.cnblogs.com/alas/p/12653133.html
Copyright © 2020-2023  润新知