說明
簡(jiǎn)述:本文將以4399小游戲《寵物連連看經(jīng)典版2》作為測(cè)試案例,通過識(shí)別小圖標(biāo),模擬鼠標(biāo)點(diǎn)擊,快速完成配對(duì)。對(duì)于有興趣學(xué)習(xí)游戲腳本的同學(xué)有一定的幫助。
運(yùn)行環(huán)境:Win10/Python3.5。
主要模塊:win32gui(識(shí)別窗口、窗口置頂?shù)炔僮鳎IL(屏幕截圖)、numpy(創(chuàng)建矩陣)、operator(比較值)、pymouse(模擬鼠標(biāo)點(diǎn)擊)。
注意點(diǎn):
1、如果安裝pymouse不成功或者運(yùn)行報(bào)錯(cuò),可以考慮先通過whl 安裝pyHook、然后再通過pip安裝pyuserinput。
2、如果報(bào)錯(cuò) [ImportError: No module named 'windows' ],可以修改__init__.py相應(yīng)的行 為 windows => pymouse.windows。
開發(fā)流程
先看看程序運(yùn)行圖吧:
總體開發(fā)思路:截取游戲主圖 ---> 分割成小圖 ---> 對(duì)比每個(gè)小圖,對(duì)比圖片相識(shí)度,編號(hào)存入矩陣 ---> 對(duì)矩陣進(jìn)行可連計(jì)算 ---> 模擬點(diǎn)擊。
獲取窗口句柄,把窗口置頂
python可以使用win32gui模塊調(diào)用Windows API實(shí)現(xiàn)對(duì)窗口的操作,使用FindWindow()方法可以獲取窗口的句柄(handle),需要傳入兩個(gè)參數(shù),第一個(gè)為父窗口句柄(這里填0即可),第二個(gè)參數(shù)是窗口的名稱(標(biāo)簽title - Google Chrome)。獲取句柄之后然后通過SetForegroundWindows() 設(shè)置窗口在前面,這里傳入游戲窗口的舉報(bào)即可,代碼如下:
截取游戲界面,分割圖標(biāo),圖片比較
這里需要花費(fèi)一些時(shí)間來(lái)校驗(yàn)程序,如果截取的圖片不好,則會(huì)影響后續(xù)操作,所以比較主要的是確認(rèn)游戲左上角和右下角這兩個(gè)坐標(biāo)值,以及每個(gè)小圖標(biāo)的寬高。如下圖所示,先截取整個(gè)游戲界面圖,然后分割小圖標(biāo),接著對(duì)每個(gè)圖標(biāo)進(jìn)行比較,然后以編號(hào)代替圖標(biāo)存入矩陣(這里的編號(hào)矩陣和游戲圖不一致,原理一樣)。
根據(jù)初始化設(shè)定的左上角和右下角兩個(gè)坐標(biāo),使用ImageGrab.grab()方法進(jìn)行截圖,傳入一個(gè)元組即可,然后對(duì)這個(gè)大圖進(jìn)行分割,切割成一個(gè)個(gè)小圖標(biāo)存入到images_list數(shù)組中。
通過上面代碼切割的小圖標(biāo),轉(zhuǎn)成數(shù)字矩陣,如果圖標(biāo)已經(jīng)存入image_type_list則返回這個(gè)索引,如果不存在,則在追加進(jìn)去,然后當(dāng)前長(zhǎng)度就是這個(gè)新加入圖標(biāo)的編號(hào),代碼如下所示:
上面的getIndex就是對(duì)比圖片,判斷圖標(biāo)是否出現(xiàn)過(是否已存在image_type_list中,沒出現(xiàn)則追加進(jìn)去),這里使用漢明距離判斷兩個(gè)圖片的相識(shí)度,設(shè)置閥值10,當(dāng)小于閥值則認(rèn)為是同一個(gè)圖片,具體代碼如下:
程序核心-圖標(biāo)連接算法(路徑尋找)
這里僅對(duì)算法代碼進(jìn)行簡(jiǎn)單分析,如果對(duì)程序不好理解,可以留言,后續(xù)可以圖文分析。
通過上面的開發(fā)流程,基本獲取如下這樣的矩陣,只要比較兩個(gè)編號(hào)相同的值進(jìn)行可連路徑尋找,如果找到即進(jìn)行模擬點(diǎn)擊操作。這里簡(jiǎn)單介紹下游戲規(guī)則:8行乘12列游戲圖標(biāo)區(qū)域,外圍的0其實(shí)表示尋找路徑的時(shí)候可以通過,例如坐標(biāo)(1, 1)可以與(1,10)進(jìn)行連接、(7, 1)和(7,2)進(jìn)行連接。
算法的思路:
路徑的尋找首先是尋找一個(gè)坐標(biāo)的橫向豎向可以直接相連的坐標(biāo)集合,比如坐標(biāo)p1(1,1)這樣的集合有[ (0,1), (1,0) ],另外一個(gè)坐標(biāo)p2(1,10)的可連集合為[ (0,10) ],然后再對(duì)p1和p2的可連坐標(biāo)集合進(jìn)行比較,如果集合中坐標(biāo)也有可連,則表示p1和p2可連,很明顯,(0,1)和(0,10)為同一行且可連,這樣就表示p1和p2兩點(diǎn)存在可連路徑了,代碼如下所示:
相信每一們萌控對(duì)狗狗的歪頭殺表示沒有抵抗力,那么狗狗歪頭是什么意思呢?其實(shí)狗狗內(nèi)心獨(dú)白是醬紫的:我們歪頭不只是在賣萌呀!
很多養(yǎng)過狗狗的人都知道,有時(shí)你在跟狗狗說話的時(shí)候,它們會(huì)歪頭看向你。它會(huì)露出很好奇的表情,一看是我們都會(huì)以為它這是在賣萌,但真相是······
一開始的時(shí)候,我們都把這種行為解讀為賣萌,它們是為了博取我們的歡心才這么做的。
但實(shí)際上并不是這樣的,有些狗狗由于鼻子太長(zhǎng),會(huì)遮擋住視線,只有歪著腦袋,才能更好的觀察我們的表情變化,從而來(lái)理解我們的意圖。
狗狗的好奇心強(qiáng),喜歡探索一些新的事情。它們同時(shí)又懂得察言觀色,當(dāng)發(fā)現(xiàn)主人的表情不對(duì)勁了,就會(huì)馬上停下來(lái)。
所以說我們的狗狗常常會(huì)偏頭,那么表明我們的狗狗是比較善解人意的,這是它們?yōu)榱四軌蚋玫刈x懂我們的情緒。表示它想明白你在說什么。
也會(huì)我們的一生中會(huì)有很多的狗狗,但狗的一生只有我們!比起我們,狗狗更加珍視這段感情,它想明白你再說些什么,表明它真的愛你!
不要把生活中的負(fù)面情緒發(fā)泄到狗狗的身上,因?yàn)槟憔褪撬囊簧?/p>