遊戲模式
這是一個2D插畫風格的益智遊戲,玩家可以點擊屏幕控制控制飛船在星球間飛躍,剛開始控制不好可能會撞上星球。
工具介紹
- Python 3.5
- Android 手機
- Adb 驅動
原理說明
通過OpenCV裏的cv2.HoughCircles()函數識別星球,通過像素顏色識別飛船,在飛船運行到兩個星球間時點擊屏幕。
程序源碼
import cv2
import numpy as np
import os
def findplanetcircle(planet):
gray_img = cv2.cvtColor(planets, cv2.COLOR_BGR2GRAY)
img = cv2.medianBlur(gray_img, 5)
# cimg = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 120,
param1=100, param2=50, minRadius=60)
for i in circles[0, :]:
# draw the outer circle
cv2.circle(planets, (i[0], i[1]), i[2], (0, 255, 0), 2)
# draw the center of the circle
cv2.circle(planets, (i[0], i[1]), 2, (0, 0, 255), 3)
return circles
def findship(planets):
(height, width, _) = planets.shape
for h in range(0, height, 5):
for w in range(1, width, 5):
(B, G, R) = planets[h][w]
if 110 < B < 125 and 80 < G < 90 and 15 < R < 25:
# cv2.circle(圖片, (w, h), 半徑, (255, 255, 255), thickness)
cv2.circle(planets, (w, h), 2, (255, 255, 255), 3)
return w, h
def computedist(point1, point2):
return np.sqrt(np.square(point1[0] - point2[0]) + np.square(point1[1] - point2[1]))
i = 1
while True:
i = i + 1
os.system('adb shell screencap -p /sdcard/autojump.png')
os.system('adb pull /sdcard/autojump.png test/' + str(i) + '.png')
planets = cv2.imread('test/' + str(i) + '.png')
circles = findplanetcircle(planets)
w, h = findship(planets)
cv2.imwrite("test/" + str(i) + "circles.jpg", planets)
ind = np.argsort(-circles[0][:, 1])
circles = circles[0][ind]
indexlist = []
for index, item in enumerate(circles):
widthcircle, heightcircle, radius = item
# 判斷目前在哪兒個星球,去掉當前星球
if np.abs(computedist(item, (w, h)) - radius) < 35:
indexlist.append(index)
# 判斷哪兒個星球已經走過,並且去掉
elif heightcircle > h:
indexlist.append(index)
planetsNum = [i for i in range(circles.shape[0])]
futurePlanet = list(set(planetsNum).difference(set(indexlist)))
circles = circles[futurePlanet]
for index, item in enumerate(circles):
widthcircle, heightcircle, radius = item
print(np.abs(computedist(item, (w, h)) - radius))
if 60 < np.abs(computedist(item, (w, h)) - radius) < 150:
print("正在點擊")
os.system('adb shell input swipe 525 1650 527 1654 2')
cv2.imwrite("test/jump" + str(i) + ".jpg", planets)
實驗結果
下圖是飛船和星球識別標註後的圖片。
TODO
圖像識別功能已經完成,可是ADB截圖再傳送到電腦有一定時間,所以點擊的時候,飛船已經飛了大半圈了,所以還需要完善,做到實時畫面傳送。