微信跳一跳輔助制作詳解

前言

微信跳一跳目前很火信柿,然后由于大家想獲得朋友圈較高的排名,這和一開始的微信運動步數(shù)一樣,出現(xiàn)了手機掛狗脖子上刷步數(shù)的現(xiàn)象宏胯,這回微信跳一跳也有外掛了,本文和你分享一下本人制作輔助思路

分析

首先玩過游戲的都知道本姥,小人會根據(jù)按壓的時長來跳相應的距離胳嘲,這個按壓時長和距離一定是成正比的,為啥這么說扣草?應該這是這個游戲的核心玩法,就是要通過玩家掌握好這個按壓時長才能得到較準確的跳躍距離颜屠,若不成正比辰妙,那這個游戲簡直太難掌握了,根本不能很好的操作小人甫窟。

這樣的話密浑,只要能夠準確計算出兩個點之間的距離,既能計算出按壓時長粗井,計算距離尔破,那就要找到起點和終點,這是做這個輔助的重點浇衬。

與游戲交互

做為一個Android開發(fā)者一定知道:ADB懒构,我們則可以通過ADB對手機進行截屏即拿到了游戲界面:

進行屏幕截圖
screencap 命令是一個用于對設備顯示屏進行屏幕截圖的 shell 實用程序。在 shell 中耘擂,此語法為:

screencap filename
要從命令行使用 screencap胆剧,請輸入以下命令:

$ adb shell screencap /sdcard/screen.png
以下屏幕截圖會話示例向您展示使用 adb shell 捕獲屏幕截圖,并使用 pull 命令從設備下載此文件:

$ adb shell
shell@ $ screencap /sdcard/screen.png
shell@ $ exit
$ adb pull /sdcard/screen.png

游戲界面拿到之后需要去分析圖片醉冤,拿到像素點信息秩霍,很顯然在python里要用到了PIL(python imaging library)這個庫,通過PIL去獲取各個像素點信息:

im = Image.open('image_file_path')
pix = im.load()
r,g,b,a = pix[x,y]

圖像中一個像素點用32位表示蚁阳,RGBA 各8位铃绒,所以我們用0~255來表示色值,RGBA組合呈現(xiàn)不同的顏色螺捐,但是一般常見的PNG是有alpha通道颠悬,而JPG是沒有alpha通道的。

基礎講完了归粉,我們開始來找起點和終點了椿疗!

找起點

首先我們都知道方塊的中心就是一個終點,觀察一下起始狀態(tài):

小人中心點

小人起始時肯定是在中心點的糠悼,通過對角線可以看出小人圓臺底部圓心即為起點届榄。那么小人的起點就是:紫色最寬的區(qū)域的中點即為小人的橫坐標;紫色的最低點即為小人的縱坐標倔喂。

紫色小人

代碼:

im = Image.open('./temp_screen.png')
pix = im.load()

min_point_x = 65535
max_point_x = 0
max_point_y = 0

global start_x
global start_y
    
for x in range(190,910):
        for y in range(1000,1250):
            r,g,b,a = pix[x,y]
            if abs(r - 56) < 5 and abs(g-59) < 5  and abs(b-102) < 5:
                min_point_x = min(min_point_x,x)
                max_point_x = max(max_point_x,x)
                start_y = y
    start_x = (min_point_x + max_point_x) / 2
    return start_x,start_y

找終點

對于終點我們可以觀察得出一個簡單的規(guī)律铝条,終點和起點總是在一條直線上靖苇,那么我們就可以算出直線函數(shù):

直線函數(shù)

(x0,y0)為起點,斜率 k 算出來是1.6(PS量一下兩個點的坐標班缰,縱坐標之差與橫坐標之差比)贤壁,這樣的話終點在小人的左側直線斜率即為-1.6,在右側直線斜率即為1.6埠忘。然后只通過斜率算出終點的橫縱坐標是不現(xiàn)實的脾拆,至少知道橫坐標或者縱坐標。

那我們分析一下橫坐標好算還是縱坐標好算呢莹妒?顯然是橫坐標名船!

  • 對于菱形來說終點的橫坐標不就是最高的那個點么?
  • 對于圓來說最上面可能是一條線段旨怠,那橫坐標不就是線段的中點么渠驼?
  • 好像沒有其它圖形了...

至此我們的問題轉換成查找方塊最上方的點的橫坐標,繼而計算出終點的縱坐標鉴腻。

從上至下一排排的掃描迷扇,直至找到最高點。而背景是一個漸變色爽哎,就需要我們每一排都要去更新一次背景色蜓席,再找這一行是否存在與背景色不一樣的像素點。

因為方塊顏色和背景圖相差較大倦青,這里用灰度值來進行比較瓮床,RGB轉灰度圖:

gray = 0.2989 * r + 0.5870 * g + 0.1140 * b

如果被比較的像素點與背景的灰度值之差小于5即認為非背景點,并保持本行所有非背景點产镐,算出橫坐標隘庄,進而算出縱坐標即可,代碼如下:

im = Image.open('./temp_screen.png')
img_L = im.convert("L")
list_x = []
is_end = False

for y in xrange(400,1100):
    base_pix = img_L.getpixel((1,y))
    for x in xrange(100,910):
        pix = img_L.getpixel((x,y))
        if abs(base_pix - pix) > 5 :
            if abs(x - start_x) > 100:
                list_x.append(x)
                is_end = True
    if is_end:
        end_x = sum(list_x)/len(list_x)
        if end_x < start_x:
            end_y = start_y-(start_x-end_x)/1.6
        else:
            end_y = start_y-(end_x-start_x)/1.6
        return end_x,end_y

操作

既然我們已經(jīng)算出起點和終點了癣亚,則可以算出兩點之間的距離:

sx,sy = cal_start()
ex,ey = cal_end()
distance = (sx - ex)**2 + (sy - ey)**2 
distance = distance ** 0.5

操作小人

這個還是利用了ADB的shell命令:

def jump(distance):
    press_time = int(distance * 1.35)
    cmd = 'adb shell input swipe 320 410 320 410 ' + str(press_time)
    os.system(cmd)

循環(huán)連續(xù)跳

最終加上循環(huán)代碼:

def start():
    while True:
        pull_screenshot()
        time.sleep(1.0)
        im = Image.open('./temp_screen.png')
        img_L = im.convert("L")
        ll = img_L.getpixel((5,5))
        if abs(ll - 47) < 5:
            return
        sx,sy = cal_start()
        ex,ey = cal_end()
        distance = (sx - ex)**2 + (sy - ey)**2 
        distance = distance ** 0.5
        print 'distance =', distance
        jump(distance)
        time.sleep(2.0)

結果

跳一跳測試結果

寫在最后:

第一次想到做輔助腳本還是看到了 wangshub 在知乎上發(fā)布的第一個版本丑掺,那時候還利用了matplotlib去手動點擊起點和終點,實現(xiàn)跳一跳述雾,由于在上班并沒有去改代碼街州,但是做為一個有圖像知識基礎的Android開發(fā)者,很快想好思路玻孟,回去即著手寫本文的代碼唆缴,晚上寫好后,朋友說人家已經(jīng)更新了黍翎,刷新一看面徽,各個版本已經(jīng)push上去了。然后看star數(shù)一天一天漲到了8K+,并且圖片識別趟紊、AI技術層出不窮氮双,完全看到一個python學習熱潮。比對發(fā)現(xiàn)本文方法略為簡單霎匈,深深感受到學習的道路很長很長戴差,還需不斷的去努力,爭取做那個引領風騷的人铛嘱!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末暖释,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子墨吓,更是在濱河造成了極大的恐慌饭入,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肛真,死亡現(xiàn)場離奇詭異,居然都是意外死亡爽航,警方通過查閱死者的電腦和手機蚓让,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來讥珍,“玉大人历极,你說我怎么就攤上這事≈缘瑁” “怎么了趟卸?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長氏义。 經(jīng)常有香客問我锄列,道長,這世上最難降的妖魔是什么惯悠? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任邻邮,我火速辦了婚禮,結果婚禮上克婶,老公的妹妹穿的比我還像新娘筒严。我一直安慰自己,他們只是感情好情萤,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布鸭蛙。 她就那樣靜靜地躺著,像睡著了一般筋岛。 火紅的嫁衣襯著肌膚如雪娶视。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天泉蝌,我揣著相機與錄音歇万,去河邊找鬼揩晴。 笑死,一個胖子當著我的面吹牛贪磺,可吹牛的內容都是我干的硫兰。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼寒锚,長吁一口氣:“原來是場噩夢啊……” “哼劫映!你這毒婦竟也來了?” 一聲冷哼從身側響起刹前,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤泳赋,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后喇喉,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體祖今,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年拣技,在試婚紗的時候發(fā)現(xiàn)自己被綠了千诬。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡膏斤,死狀恐怖徐绑,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情莫辨,我是刑警寧澤傲茄,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站沮榜,受9級特大地震影響盘榨,放射性物質發(fā)生泄漏。R本人自食惡果不足惜蟆融,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一较曼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧振愿,春花似錦捷犹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至档桃,卻和暖如春枪孩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工蔑舞, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留拒担,地道東北人。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓攻询,卻偏偏與公主長得像从撼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子钧栖,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348