OpenCV玩微信小遊戲星途WeGoing

遊戲模式

這是一個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截圖再傳送到電腦有一定時間,所以點擊的時候,飛船已經飛了大半圈了,所以還需要完善,做到實時畫面傳送。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章