參考大佬們的博客,湊出了陰陽師的簡單掛機腳本,對各個博主進行感謝,鞠躬.jpg
實現原理:
對各個按鈕等需要點擊的地方進行截圖,然后對整個屏幕截屏,通過模板匹配得到截圖在截屏中的坐標位置,進行點擊
實現方法:
對整個屏幕進行截圖,並保存
1 ####截圖方法1#### 2 import win32gui 3 import win32ui 4 import win32con 5 import win32api 6 def Printscreen(): 7 # 獲取桌面 8 hdesktop = win32gui.GetDesktopWindow() 9 10 # 分辨率適應 11 width = win32api.GetSystemMetrics(win32con.SM_CXVIRTUALSCREEN) 12 height = win32api.GetSystemMetrics(win32con.SM_CYVIRTUALSCREEN) 13 left = win32api.GetSystemMetrics(win32con.SM_XVIRTUALSCREEN) 14 top = win32api.GetSystemMetrics(win32con.SM_YVIRTUALSCREEN) 15 # width=1920 # 因為用win32api.GetSystemMetrics獲取的分辨率不對,於是我直接手輸入進去的 16 # height=1080 17 18 # 創建設備描述表 19 desktop_dc = win32gui.GetWindowDC(hdesktop) 20 img_dc = win32ui.CreateDCFromHandle(desktop_dc) 21 22 # 創建一個內存設備描述表 23 mem_dc = img_dc.CreateCompatibleDC() 24 25 # 創建位圖對象 26 screenshot = win32ui.CreateBitmap() 27 screenshot.CreateCompatibleBitmap(img_dc, width, height) 28 mem_dc.SelectObject(screenshot) 29 30 # 截圖至內存設備描述表 31 mem_dc.BitBlt((0, 0), (width, height), img_dc, (left, top), win32con.SRCCOPY) 32 33 # 將截圖保存到文件中 34 screenshot.SaveBitmapFile(mem_dc, 'yuan.png') 35 36 # 內存釋放 37 mem_dc.DeleteDC() 38 win32gui.DeleteObject(screenshot.GetHandle()) 39 40 # 測試 41 Printscreen()
1 ####截圖方法2#### 2 from PIL import Image 3 from PIL import ImageGrab 4 5 def Printscreen(): 6 # 截圖坐標 左上角 ,右下角 7 size = (0, 0,1920,1080) 8 img = ImageGrab.grab(size) 9 # 保存截圖 10 img.save("yuan.png") 11 print('截圖進行了一次刷新') 12 # 打開截圖 13 # img.show() 14 15 # 測試 16 Printscreen()
通過模板匹配得到截圖的坐標位置
模板匹配參考博客
圖像篩選參考博客
注:模板匹配具有自身的局限性,主要表現在它只能進行平行移動,若原圖像中的匹配目標發生旋轉或大小變化,該算法無效。所以打開陰陽師后不要進行放大或縮小。
1 import cv2 2 import numpy as np 3 from matplotlib import pyplot as plt 4 import math 5 6 ###圖像匹配### 7 def Image_Discern(imgone,imgtwo): 8 # 1.模板匹配 9 # 大圖 10 img = cv2.imread(imgone) 11 img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 12 13 # 小圖 14 template = cv2.imread(imgtwo, 0) 15 h, w = template.shape[:2] # rows->h, cols->w 16 img2 = img.copy() 17 18 # 對比圖像 19 res = cv2.matchTemplate(img_gray, template, cv2.TM_SQDIFF_NORMED) 20 21 # 返回坐標 22 min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) 23 top_left = min_loc 24 bottom_right = (top_left[0] + w, top_left[1] + h) 25 26 # 計算中心坐標 27 a1, a2 = top_left 28 b1, b2 = bottom_right 29 c1 = (a1 + w/2)*0.8 # 0.8匹配屏幕分辨率(因為分辨率原因這里乘0.8用於適應平復分辨率坐標位置) 30 c2 = (a2 + h/2)*0.8 31 e1 = math.ceil(c1) 32 e2 = math.ceil(c2) 33 d1 = (e1, e2) 34 # print('中心坐標為:' , d1) 35 36 ###測試圖像匹配,彈出圖像顯示匹配位置### 37 # 在匹配點畫小圓心 38 # cv2.circle(res, top_left, 10, 0, 2) 39 # cv2.imshow("res", res) 40 41 # # 畫矩形 42 # cv2.rectangle(img2, top_left, bottom_right, (0, 255, 0), 2) 43 # cv2.imshow("img2",img2) 44 # cv2.waitKey(0) 45 46 # 兩張圖片是否匹配 47 # print('各個參數為:',min_val, max_val, min_loc, max_loc) 48 49 ###進行圖像篩選### 50 if min_val <= 0.03: 51 # print('圖片匹配') 52 return(d1) 53 else: 54 # print('圖片不匹配') 55 return(0) 56 57 58 # 測試 59 # Image_Discern('e1.png','a2.png') # (大圖,小圖)匹配圖像
通過坐標位置進行點擊
鼠標點擊參考博客
1 import win32api 2 import win32con 3 import win32gui 4 import time 5 import random 6 7 def xunzhao(): 8 9 wdname = u'陰陽師-網易游戲' 10 # 取得窗口句柄 11 hwnd = win32gui.FindWindow(0, wdname) 12 if not hwnd: 13 print("窗口找不到,請確認窗口句柄名稱:【%s】" % wdname ) 14 exit() 15 # 窗口顯示最前面 16 win32gui.SetForegroundWindow(hwnd) 17 18 def move_click(x, y, t=0): # 移動鼠標並點擊左鍵 19 suiji1 = random.randint(0,10) 20 suiji2 = random.randint(0,10) 21 22 # print('鼠標抖動隨機數為:+',suiji2,' +',suiji1) 23 win32api.SetCursorPos((x+suiji1, y+suiji2)) # 設置鼠標位置(x, y),設置隨機數,以防被封 24 time.sleep(0.1) 25 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0) 26 win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) # 點擊鼠標左鍵 27 # print('模擬點擊') 28 return 0 29 30 # 測試 31 # while True : 32 # suiji = random.randint(0,5) #獲得隨機數 33 # xunzhao() #游戲頂置,獲得句柄 34 # time.sleep(suiji) #間隔時間 35 # move_click(1280, 685) #坐標點擊
一個簡陋的實例
有基本的方法后,然后就可以寫代碼進行掛機了。
貼一個自己刷探索的代碼,其中click模塊為鼠標模擬點擊,printscreen模塊為截屏,image_discern模塊為模板匹配
1 import click 2 import printscreen 3 import image_discern 4 import time 5 6 ###進行圖標點擊### 7 def Identify_Click(little): 8 a = 0.1 9 click.xunzhao() 10 time.sleep(a) # 間隔秒數 11 printscreen.Printscreen() # 截圖 12 time.sleep(a) 13 b1 = image_discern.Image_Discern('yuan.png', little) #圖像對比 14 for i in range(1,10): 15 if b1 == 0: 16 print('准備再次尋找第',i,'次') 17 time.sleep(a) 18 click.xunzhao() 19 time.sleep(a) 20 printscreen.Printscreen() 21 time.sleep(a) 22 b1 = image_discern.Image_Discern('yuan.png', little) 23 else: 24 time.sleep(a) 25 printscreen.Printscreen() # 截圖 26 b1 = image_discern.Image_Discern('yuan.png', little) #圖像對比 27 a1, a2 = b1 #地址賦值 28 click.move_click(a1, a2) #模擬點擊 29 time.sleep(a) 30 break 31 32 ###尋找場景內是否有相應圖標### 33 def Identify_Click_Seek(little): 34 a = 0.1 35 click.xunzhao() 36 time.sleep(a) # 間隔秒數 37 printscreen.Printscreen() # 截圖 38 time.sleep(a) 39 b1 = image_discern.Image_Discern('yuan.png', little) #圖像對比 40 if b1 == 0: 41 # print('沒有相應圖標') 42 return(False) 43 else: 44 # print('找到相應圖標') 45 return(True)
上面那代碼塊為identify_click模塊
1 import time 2 import identify_click 3 import random 4 5 def Tansuo(): 6 7 b=0 8 while True: 9 a = ('-----------------') 10 ##判斷體力是否足夠## 11 if identify_click.Identify_Click_Seek('./png/tansuo/tansuo13.png'): 12 print(a) 13 print('體力不足') 14 break #結束循環 15 ###組隊結束戰斗### 16 if identify_click.Identify_Click_Seek('./png/tansuo/tansuo17.png'): 17 print(a) 18 print('戰斗結束,回到組隊頁面') 19 break #結束循環 20 ##判斷是否結束## 21 elif identify_click.Identify_Click_Seek('./png/tansuo/tansuo12.png'): 22 print(a) 23 print('探索結束!!') 24 break 25 ##判斷戰斗結束## 26 elif identify_click.Identify_Click_Seek('./png/tansuo/tansuo04.png'): 27 identify_click.Identify_Click('./png/tansuo/tansuo04.png') 28 print(a) 29 print('戰斗結束') 30 continue #跳出本次循環 31 ##判斷准備按鈕## 32 elif identify_click.Identify_Click_Seek('./png/tansuo/tansuo08.png'): 33 identify_click.Identify_Click('./png/tansuo/tansuo08.png') 34 print(a) 35 print('戰斗開始') 36 while True: 37 if identify_click.Identify_Click_Seek('./png/tansuo/tansuo15.png'): 38 identify_click.Identify_Click('./png/tansuo/tansuo15.png') 39 break 40 elif identify_click.Identify_Click_Seek('./png/tansuo/tansuo04.png'): 41 identify_click.Identify_Click('./png/tansuo/tansuo04.png') 42 break 43 elif identify_click.Identify_Click_Seek('./png/tansuo/tansuo16.png'): 44 identify_click.Identify_Click('./png/tansuo/tansuo16.png') 45 else: 46 time.sleep(0.1) 47 if identify_click.Identify_Click_Seek('./png/tansuo/tansuo15.png'): 48 print('!!!!!!!!!!!') 49 print('!戰斗失敗,中止腳本!') 50 print('!!!!!!!!!!!') 51 break 52 continue #跳出本次循環 53 ##BOSS## 54 elif identify_click.Identify_Click_Seek('./png/tansuo/tansuo07.png'): 55 print(a) 56 print('發現BOSS') 57 identify_click.Identify_Click('./png/tansuo/tansuo07.png') 58 continue 59 ##小怪## 60 elif identify_click.Identify_Click_Seek('./png/tansuo/tansuo03.png'): 61 print(a) 62 print('發現小怪') 63 identify_click.Identify_Click('./png/tansuo/tansuo03.png') 64 continue 65 ##獎勵寶箱## 66 elif identify_click.Identify_Click_Seek('./png/tansuo/tansuo09.png'): 67 identify_click.Identify_Click('./png/tansuo/tansuo09.png') 68 time.sleep(random.randint(1,2)) 69 while True: 70 if identify_click.Identify_Click_Seek('./png/tansuo/tansuo10.png'): 71 identify_click.Identify_Click('./png/tansuo/tansuo11.png') 72 break 73 else: 74 time.sleep(2) 75 print(a) 76 print('領取獎勵寶箱') 77 continue 78 ##進行走動## 79 elif identify_click.Identify_Click_Seek('./png/tansuo/tansuo05.png'): 80 print(a) 81 print('進行走動') 82 b = b+1 83 if b < 5: 84 identify_click.Identify_Click('./png/tansuo/tansuo05.png') 85 print('向右') 86 time.sleep(random.randint(3,4)) #間隔3~4秒 87 continue 88 else: 89 identify_click.Identify_Click('./png/tansuo/tansuo06.png') 90 print('向左') 91 time.sleep(random.randint(3,4)) #間隔3~4秒 92 continue 93 94 time.sleep(0.5) #間隔3~4秒 95 return(True) 96 97 # 測試 98 Tansuo()
當中的圖片
這些是最近東拼西湊的代碼,簡單的代替了下無聊的手點鼠標環節。
還有一個簡單實現的方法,運用pyautogui庫,進行鼠標點擊、截屏等操作,pyautogui庫使用方法參考博客
最后再次感謝各位大佬的博客