本文将梳理github上最火的wechat_jump_game的实现思路,并解析其图像处理部分源码
首先废话少说先看效果
核心思想
获取棋子到下一个方块的中心点的距离
计算触摸屏幕的时间
点击屏幕
重要方法
计算棋子到下一个方块中心点的距离
使用 adb shell screencap -p 命令获取手机当前屏幕画面 再通过图像上的信息找出棋子的坐标和下一个方块中心点的坐标 然后通过两点间距离公式计算出距离计算触摸屏幕的时间
T=A * S
其中S为上步算出的像素距离,T为按压时间(ms),A为一个系数这个系数会随着屏幕分辨率的变化而变化,在1920*1080的屏幕下这个系数为1.35,在2560*1440的屏幕下这个系数为1.475
点击屏幕
adb shell input swipe x y x y time(ms)
这条命令能够点击手机屏幕x,y位置time(ms)
图像处理部分源码解析
图像处理部分代码都在 find_piece_and_board(im) 方法中
通过输入的图像im计算出棋子的坐标点以及下一个方块中心的坐标点
在find_piece_and_board的方法中一进来就是下面的两个嵌套在一起的for循环:
for i in range(int(h / 3), int(h * 2 / 3), 50): last_pixel = im_pixel[0, i] for j in range(1, w): pixel = im_pixel[j, i] # 不是纯色的线,则记录 scan_start_y 的值,准备跳出循环 if pixel[0] != last_pixel[0] or pixel[1] != last_pixel[1] or pixel[2] != last_pixel[2]: scan_start_y = i - 50 break if scan_start_y: break
这段代码的作用就是从屏幕2/3的位置向下寻找不是纯色的线。并将找到位置的纵坐标-50作为,寻找棋子和方块的起始坐标。这样可以简化以后搜索的工作量,因为在这个横坐标以上是没有东西的。
接下来是查找棋子坐标的代码
# 查找棋子坐标 # piece_x_sum 横坐标总量 piece_x_c 点的个数 piece_y_max 纵坐标最大值 # 从 scan_start_y 开始往下扫描,棋子应位于屏幕上半部分,这里暂定不超过 2/3 for i in range(scan_start_y, int(h * 2 / 3)): for j in range(scan_x_border, w - scan_x_border): # 横坐标方面也减少了一部分扫描开销 pixel = im_pixel[j, i] # 根据棋子的最低行的颜色判断,找最后一行那些点的平均值,这个颜色这样应该 OK,暂时不提出来 if (50 < pixel[0] < 60) and (53 < pixel[1] < 63) and (95 < pixel[2] < 110): piece_x_sum += j piece_x_c += 1 piece_y_max = max(i, piece_y_max) if not all((piece_x_sum, piece_x_c)): return 0, 0, 0, 0 # 平均横坐标 piece_x = int(piece_x_sum / piece_x_c) # 纵坐标最大值-底座一半的高度 piece_y = piece_y_max - piece_base_height_1_2 # 上移棋子底盘高度的一半
新闻热点
疑难解答