明日方舟腳本1.0(python\adb\cv2)


一、目的

《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位置為:MuMu\emulator\nemu\vmonitor\bin

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM