前言:最近跳一跳太火,大家都在寫,今天把原理來說說,說得不對歡迎指出!
注:請不要加我微信,免得尷尬!(^_^)
準備工作:
1.電腦
2.數據線
3.安卓手機(因爲我這渣渣電腦帶不動模擬器,只能寫真機版)
第一步:電腦安裝ADB(https://developer.android.google.cn/studio/releases/platform-tools.html)
下載解壓就可以了
第二步:大家不需要配置啥環境變量,我搞半天沒搞懂,直接在ADB目錄創建易語言源碼就不需要配置了!
第三步:手機用數據線連接電腦。手機打開USB調試,還需要打開手機USB調試下面的“模擬按鍵”
沒有“模擬按鍵”的就打開“USB安全權限”,以我VIVOX20A打開“USB安全權限”打不開,
問客服才知道要先退出VIVO賬號,再登陸,才能打開。
第四步:打開第二步創建的易語言源碼,創建圖片框、兩個按鈕、一個編輯框。界面如下
以上工作做完之後,先來測試下ADB,看是否連接到手機
到ADB目錄創建一個a.bat
a.bat用記事本打開
輸入”start"保存
運行a.bat得到一個CMD界面
在CMD裏面輸入“adbshellinputkeyevent3”(這個是按下手機主頁面鍵)回車,看手機是否回到主頁面
並且CMD裏面沒有輸出錯誤!
以上準備工作做完,下面進入代碼階段:
自動模式:
因爲跳一跳背景和道具多爲漸變色,所以識別不是太好,說下原理(我用這個模式只跳220多點)
第一步:截取手機屏幕保存爲圖片,並送傳到電腦,加載到圖片框,代碼如下(子程序名:那麼我們就開始跳吧)
.版本 2
.子程序 那麼我們就開始跳吧
' 刪除之前取到的截圖
.判斷開始 (集開始 = 假)
返回 ()
.默認
.判斷結束
刪除文件 (取運行目錄 () + “\tiaoyitiao.png”)
' 使用adb命令截取手機屏幕
運行 (“adb shell screencap -p /sdcard/tiaoyitiao.png”, 真, 1) ' 手機截屏保存到SD卡根目錄
運行 (“adb pull /sdcard/tiaoyitiao.png”, 真, 1) ' 圖片傳送到電腦程序目錄上
圖片框1.圖片 = 讀入文件 (取運行目錄 () + “/tiaoyitiao.png”) ' 把圖片顯示到軟件上
.判斷開始 (集手動 = 假)
取棋子底部座標 ()
.默認
代碼都有備註,可以看看,看到最後面有個“取棋子底部座標()”
那麼下一步代碼
.版本 2
.子程序 取棋子底部座標
.局部變量 color, 整數型
.局部變量 刷子句柄, 整數型
.局部變量 畫筆句柄, 整數型
.局部變量 r, 整數型
.局部變量 g, 整數型
.局部變量 b, 整數型
.局部變量 x, 整數型
.局部變量 y, 整數型
' 臨時代碼 ()
dc = GetDC (圖片框1.取窗口句柄 ()) ' 設置場景
畫筆句柄 = CreatePen (0, 1, #黑色) ' 畫筆顏色 、 形狀、粗細
刷子句柄 = CreateSolidBrush (#紅色) ' 刷子顏色
x = 0
y = 270 ' 定位Y270 加快速度
.判斷循環首 (真)
x = x + 1
.判斷開始 (x > 圖片框1.寬度) ' X軸不能大於組件寬度
x = 1
y = y + 1
.判斷 (y > 圖片框1.高度) ' Y軸不能大於組件高度
_按鈕1_被單擊 ()
信息框 (“未找到”, 0, , )
跳出循環 ()
.默認
.判斷結束
color = GetPixel (dc, x, y) ' 取座標顏色
.判斷開始 (color = 6042679) ' 棋子特徵顏色
跳出循環 ()
.判斷 (color = 6502712) ' 棋子特徵顏色
跳出循環 ()
.判斷 (color = 6371383) ' 棋子特徵顏色
跳出循環 ()
.判斷 (color = 6699831) ' 棋子特徵顏色
跳出循環 ()
.默認
.判斷結束
.判斷循環尾 ()
SelectObject (dc, 畫筆句柄) ' 更換畫筆
Ellipse (dc, x - 3, y - 3, x + 3, y + 3) ' 畫空心圓
SelectObject (dc, 刷子句柄) ' 更新刷子
Ellipse (dc, x - 3, y - 3, x + 3, y + 3) ' 畫實心圓
DeleteObject (刷子句柄) ' 釋放刷子
DeleteObject (畫筆句柄) ' 釋放畫筆
棋子.x = x ' 記錄棋子座標
棋子.y = y
輸出調試文本 (“棋子顏色:” + 到文本 (color))
取小板登座標 ()
可以看到,棋子我是直接找的4個顏色,經過多方測試,這四個顏色都能識別到棋子底部
找到這個顏色就把座標記錄下來。並且用刷子在座標的位置畫個實心圓顯示給我們看,
方便調試!
而且Y軸是從270開始的,一行一行的找,加快速度,按我的圖片框高度是從270的!!!!
棋子的座標找到了,那麼我們再找“板凳”的座標(“板凳”的座標識別不太理想)
.版本 2
.子程序 取小板登座標
.局部變量 color, 整數型
.局部變量 刷子句柄, 整數型
.局部變量 畫筆句柄, 整數型
.局部變量 r, 整數型
.局部變量 g, 整數型
.局部變量 b, 整數型
.局部變量 x, 整數型
.局部變量 y, 整數型
.局部變量 color2, 整數型
' 臨時代碼 ()
dc = GetDC (圖片框1.取窗口句柄 ())
畫筆句柄 = CreatePen (0, 1, #黑色)
刷子句柄 = CreateSolidBrush (#綠色)
x = 0
y = 140 ' 默認從200開始,加快取色速度
.判斷循環首 (真)
x = x + 1
.判斷開始 (x > 圖片框1.寬度) ' 像素x不超過組件的寬度
x = 1
y = y + 1
.判斷 (y > 圖片框1.高度) ' 像素Y不超過組件的高度
_按鈕1_被單擊 ()
信息框 (“未找到”, 0, , )
跳出循環 ()
.默認
.判斷結束
color = GetPixel (dc, x, y) ' 獲取座標顏色值
.判斷開始 (color2 = 0) ' 如果color2=0 ,也就是第一次取色,把取到的顏色給他保存
color2 = color
.判斷 (color - color2 > 78000) ' 背景顏色是個漸變色,差值不超過10萬 超過則說明,到達要跳的物體頂部
跳出循環 ()
.判斷 (color = 16185078) ' 白色石頭
跳出循環 ()
.判斷 (color = 7435156) ' 褐色石頭
跳出循環 ()
.判斷 (color = 7434609) ' 黑灰石頭
跳出循環 ()
.判斷 (color = 7040912)
跳出循環 ()
.判斷 (color = 15856113)
跳出循環 ()
.判斷 (color = 6655572)
跳出循環 ()
.判斷 (color = 9291745)
跳出循環 ()
.默認
.判斷結束
.判斷循環尾 ()
SelectObject (dc, 畫筆句柄) ' 把畫筆載入
y = y + 20
Ellipse (dc, x - 5, y - 5, x + 5, y + 5) ' 用畫筆畫空心圓
SelectObject (dc, 刷子句柄) ' 更換成刷子
Ellipse (dc, x - 5, y - 5, x + 5, y + 5) ' 用刷子畫實心圓
DeleteObject (刷子句柄)
DeleteObject (畫筆句柄)
馬桶.x = x
馬桶.y = y
輸出調試文本 (“馬桶顏色:” + 到文本 (color))
屁股定理 ()
可以看到“板凳”的Y軸從140開始的,因爲通常“板登”都在棋子上方
找的“板凳”是“板凳”的最上面的一個點的座標,並且畫個實心圓,方便調試
找到的座標也記錄下來
棋子、板凳座標識別界面圖如下
可以看到棋子的底部有個紅色的實心圓顯示找到的座標
板凳上也有個綠色的實心圓顯示座標(板凳的綠色圓在板凳中間偏上是因爲我識別的時候是識別到頂部的,然後我在代碼中把板凳的Y軸+30個像素,因爲要取板凳中間的座標的算法還沒想出來,比較麻煩,所以就只取了一個頂部的座標,然後下移30個像素,像小板凳啥的30個剛好)
其實找板凳的顏色只有上面兩個判斷,後來分數多了,背景色不斷變化,就有添加了一個固定的顏色
上面棋子和板凳的座標找到了,那麼進入“勾股定理”(其實我小學沒畢業,早忘了這東西了,百度重學的)
計算棋子到板凳直線距離代碼如下:
.版本 2
.子程序 屁股定理
.局部變量 x, 整數型, , , 寬度
.局部變量 y, 整數型, , , 高度
.局部變量 平方, 雙精度小數型
.局部變量 時間, 整數型
.判斷開始 (棋子.x > 馬桶.x) ' 如果馬桶的x軸小於棋子的x軸,,也就是馬桶在左邊,我們要往左邊跳
x = 棋子.x - 馬桶.x
.默認
x = 馬桶.x - 棋子.x ' 往右跳
.判斷結束
y = 棋子.y - 馬桶.y ' 取得高度
' 直角三角型的屁股定理
平方 = x × x + y × y
平方 = 求平方根 (平方) ' 取得棋子到馬桶的直線距離
平方 = 平方 × 到數值 (編輯框1.內容) ' 計算要跳的時間(毫秒)
時間 = 到整數 (平方)
我要跳高 (時間)
上面求到直線距離爲什麼要*編輯框的微調呢?
1.大多手機屏幕分辨率不一樣,得到的截圖尺寸有大小
2.截圖的圖片加載到圖片框是經過縮放的,而且是按比例縮放
3.一般我測試出的按壓時間在200-900毫秒之間
也就是得到的直線距離是30的話,要按到300毫秒,那麼微調爲10
以我的手機和我設置的圖片框尺寸,微調在4.8-5.0之間
最後把得到的按壓時間傳給下一子程序去執行手機按壓
.版本 2
.支持庫 spec
.子程序 我要跳高
.參數 時間, 整數型
.局部變量 a, 文本型
.如果真 (集開始 = 假)
返回 ()
.如果真結束
運行 (“adb shell input swipe 251 255 380 395 ” + 到文本 (時間), 真, 1)
延遲 (2000)
那麼我們就開始跳吧 ()
運行的那段代碼是讓手機模擬滑動,從什麼地方按住滑動到什麼地方,最後一個就是滑動的時間(毫秒)
以上自動跳一跳就完了,測試不理想,就加了個手動檔,這個簡單
.版本 2
.子程序 _按鈕手動檔_被單擊
集開始 = 真
集手動 = 真
那麼我們就開始跳吧 ()
按下手動檔,取一次手機屏幕到圖片框
.版本 2
.子程序 _圖片框1_鼠標左鍵被按下, 邏輯型
.參數 橫向位置, 整數型
.參數 縱向位置, 整數型
.參數 功能鍵狀態, 整數型
' dc = GetDC (0)
' 輸出調試文本 (GetPixel (dc, 取鼠標水平位置 (), 取鼠標垂直位置 ()))
棋子.x = 取鼠標水平位置 ()
棋子.y = 取鼠標垂直位置 ()
.子程序 _圖片框1_鼠標左鍵被放開, 邏輯型
.參數 橫向位置, 整數型
.參數 縱向位置, 整數型
.參數 功能鍵狀態, 整數型
馬桶.x = 取鼠標水平位置 ()
馬桶.y = 取鼠標垂直位置 ()
屁股定理 ()
鼠標在圖片框的棋子下按下不放
到板凳的中心位置放開鼠標,就得到了棋子和板凳的座標
再調用上面寫完的“屁股定理()”
之後就是按鼠標,放鼠標了,不需要再按手動檔按鈕
附上源碼,無模塊,無病毒!移步:http://down.51cto.com/data/2387983