1.?? OpenCV:模板匹配。??? 獲得小跳棋中心位置
2.?? OpenCV:邊緣檢測。??? 獲得下一方塊中心位置
Python+ADB+OpenCv,實現(xiàn)「 跳一跳 」自動化。
/ 01 / ADB
ADB工具即Android Debug Bridge(安卓調(diào)試橋) tools。
ADB 是一個命令行窗口,用于通過電腦端與模擬器或者真實設(shè)備交互。
與之前小F接觸過的Appium有點相似。
ADB的安裝很簡單,就是將安裝包解壓后,將路徑添加到系統(tǒng)的環(huán)境變量中即可。
然后使用Python的os模塊執(zhí)行ADB命令。
def get_screenshot():
# 截取手機的屏幕
os.system('adb shell /system/bin/screencap -p /sdcard/screencap.png')
# 把模擬器里面的文件或文件夾傳到電腦上
os.system('adb pull /sdcard/screencap.png screencap.png')
def jump(distance):
# 設(shè)置按壓時間,系數(shù)為1.35
press_time = int(distance * 1.35)
# 生成隨機手機屏幕模擬觸摸點,防止成績無效
# 生成隨機整數(shù)(0-9),最終數(shù)值為(0-90)
rand = random.randint(0, 9) * 10
# adb長按操作,即在手機屏幕上((320-410),(410-500))坐標處長按press_time毫秒
cmd = ('adb shell input swipe %i %i %i %i ' + str(press_time)) % (320 + rand, 410 + rand, 320 + rand, 410 + rand)
# 輸出adb命令
print(cmd)
# 執(zhí)行adb命令
os.system(cmd)
本次涉及到的ADB命令,就只有三個,不多。
一個截屏,一個推送手機截圖到電腦上,最后模擬長按手機屏幕。
/ 02 / 跳動實現(xiàn)
先檢測游戲結(jié)束畫面。
判斷是否需要結(jié)束游戲程序。
# 游戲結(jié)束的模板圖像
temp_end = cv2.imread('end.jpg', 0)
def game_over(img):
""" 模板匹配,檢測是否要將程序結(jié)束 """
# 如果在游戲截圖中匹配到帶"再玩一局"字樣的模板,則循環(huán)中止
res_end = cv2.matchTemplate(img, temp_end, cv2.TM_CCOEFF_NORMED)
if cv2.minMaxLoc(res_end)[1] > 0.95:
print('Game over!')
return True
模板匹配原理圖如下。
當(dāng)返回的最大矩陣值大于0.95時,則認為原始圖像中肯定出現(xiàn)了再玩一局字樣。
則游戲結(jié)束,程序也隨之結(jié)束。
小跳棋的模板匹配代碼如下。
主要是獲取小跳棋的位置,即「跳一跳」起點位置參數(shù)。
# 讀取小跳棋模板圖像
temple = cv2.imread('temple.png', 0)
# 獲取小跳棋模板圖像的高和寬
th, tw = temple.shape[:2]
def get_start(img):
""" 模板匹配,獲取跳一跳起點的位置參數(shù)(小跳棋) """
# 使用標準相關(guān)系數(shù)匹配,1表示完美匹配,-1表示糟糕的匹配,0表示沒有任何相關(guān)性
result = cv2.matchTemplate(img, temple, cv2.TM_CCOEFF_NORMED)
# 使用函數(shù)minMaxLoc,確定匹配結(jié)果矩陣的最大值和最小值(val),以及它們的位置(loc)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
# 得到小跳棋的中心位置參數(shù)
return max_loc[0] + 47, max_loc[1] + 208
得到結(jié)果如下。
下面通過OpenCV的邊緣檢測獲取「跳一跳」的終點位置。
def get_end(img):
""" 邊緣檢測,獲取跳一跳終點的位置參數(shù)(方塊) """
# 高斯模糊
img_rgb = cv2.GaussianBlur(img, (5, 5), 0)
# 邊緣檢測
canny_img = cv2.Canny(img_rgb, 1, 10)
# 獲得邊緣檢測圖像的高和寬
H, W = canny_img.shape
# 第一個頂點的高度
y_top = np.nonzero([max(row) for row in canny_img[400:]])[0][0] + 400
# 第一個頂點的寬度
x_top = int(np.mean(np.nonzero(canny_img[y_top])))
# 跳過小白圈,然后遍歷
y_bottom = y_top + 80
for row in range(y_bottom, H):
if canny_img[row, x_top] != 0:
y_bottom = row
break
# 得到方塊的中心點
x_center, y_center = x_top, (y_top + y_bottom) // 2
return x_center, y_center
邊緣檢測原理圖如下。
最后便是主程序啦。
# 循環(huán)直到游戲失敗結(jié)束
for i in range(10000):
# 將安卓手機上的截圖移到電腦當(dāng)前文件夾下
get_screenshot()
# 讀取截圖圖像
img = cv2.imread('screencap.png', 0)
# 游戲結(jié)束
if game_over(img):
break
# 得到起點位置參數(shù)
x_start, y_start = get_start(img)
# 獲取終點位置參數(shù)
x_end, y_end = get_end(img)
# 將起點位置繪制出來,一個圓
cv2.circle(img, (x_start, y_start), 10, 255, -1)
# 將終點位置繪制出來,一個圓
img_end = cv2.circle(img, (x_end, y_end), 10, 255, -1)
# 保存圖片
cv2.imwrite('end.png', img_end)
# 計算起點和終點的直線距離,勾三股四弦五
distance = (x_start - x_end) ** 2 + (y_start - y_end) ** 2
distance = distance ** 0.5
# 根據(jù)獲得的距離來設(shè)置按壓時長
jump(distance)
time.sleep(1.3)
下面就來看一下「跳一跳」自動跳躍的視頻。
輕輕松松得分,毫無問題。
/ 03 / 總結(jié)
相關(guān)工具及代碼已上傳網(wǎng)盤,公眾號回復(fù) 「跳一跳」 即可獲取。
安裝好ADB工具,然后通過數(shù)據(jù)線將安卓手機和電腦連接。
最后運行代碼, 親測有效。
當(dāng)然代碼還是有待優(yōu)化的,如下圖~
一方面是得分不高,另一方面就是會被檢測到作弊...
總結(jié)
以上所述是小編給大家介紹的使用Python實現(xiàn)跳一跳自動跳躍功能 ,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
如果你覺得本文對你有幫助,歡迎轉(zhuǎn)載,煩請注明出處,謝謝!
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

