实现思路:
调用adb命令,截图寻找小小人的底部中心点role(从下到上扫描,直到找到小小人相同像素的点,至于小小人像素点rgb是什么,可以使用photoshop查看)寻找棋盘最高点top,然后寻找棋盘最右点。根据最高点与最右点,确定棋盘中心点border计算role与border之间的直线距离,然后设置按压时间=距离*按压系数调用adb 命令,按压屏幕
完整代码,测试机Oppo r11
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from PIL
import Image, ImageDraw
import math
import os
import time
import subprocess
# 小小人底部RGB
role_bottom_rgb = (58, 58, 102
)
# 小小人头部RGB
role_top_rgb = (65, 65, 90
)
# 白色中心点 RGB
white_point = (245, 245, 245
)
# 按压系数
press_coefficient = 1.35
def get_screenshot():
"""
获取截图信息
:return:
"""
process = subprocess.Popen(
'adb shell screencap -p', shell=
True,
stdout=
subprocess.PIPE)
binary_screenshot =
process.stdout.read()
binary_screenshot = binary_screenshot.replace(b
'\r\r\n', b
'\n')
with open('autojump.png',
'wb') as f:
f.write(binary_screenshot)
time.sleep(1
)
img = Image.open(
'autojump.png')
return img
def is_similar(rgb1, rgb2, degree=20
):
"""
判断颜色是否相近
:param rgb1:
:param rgb2:
:param degree:
:return:
"""
return abs(rgb1[0] - rgb2[0]) <= degree
and abs(
rgb1[1] - rgb2[1]) <= degree
and abs(rgb1[2] - rgb2[2]) <=
degree
def calculate_jump_distance(img):
"""
计算跳一跳的距离
:param image:
:return:
"""
draw =
ImageDraw.Draw(img)
im_pixel =
img.load()
w, h =
img.size
# 设置有效扫描区域
min_x = 100
max_x = w - 10
min_y = 400
max_y = h - 100
# step1:寻找小小人底座位置
role_start_x =
0
role_end_x =
0
role_y =
0
find_role =
False
# y轴从下往上扫描
for y
in range(max_y, min_y, -1
):
# 找到小小人最低部一行,退出y轴循环
if find_role:
break
# y轴未找到最低一行,则继续遍历x轴元素点
# x轴从左到右扫描
for x
in range(min_x, max_x):
current_rgb = im_pixel[x, y]
# 当前像素RGB值
# 寻找到小人底座首位像素点
if is_similar(current_rgb, role_bottom_rgb, 5
):
if not find_role:
# 找到首位像素点
find_role =
True
role_start_x =
x
role_y = y
# 小人底座中心点的y轴坐标已确定
# 小人底座最右侧像素点定位,条件:首位像素点已找到,在当前y轴上继续遍历x轴,当当前像素不在小小人中时,前一个像素点为底座最右点
if find_role
and not is_similar(current_rgb, role_bottom_rgb, 5
):
role_end_x = x - 1
break
# 小小人底座中心点
role_x = (role_start_x + role_end_x) / 2
role =
(role_x, role_y)
draw.point([role], fill=(255
, 0, 0))
# step2:寻找棋盘顶点:从上往下,从左到右扫描,寻找首位与初始点不一样的像素
# 解决小小人头部出现在最顶部时的BUG,在x轴扫描时,跳过小小人位置[role_start_x,role_end_x]
top_x =
0
top_y =
0
top_rgb =
None
role_top_flag =
False
for y
in range(min_y, max_y):
for x
in range(min_x, max_x):
current_rgb =
im_pixel[x, y]
# 首先出现小小人的头部
if not role_top_flag:
if is_similar(current_rgb, role_top_rgb, 40
):
print(
"首先出现小小人头部!")
role_top_flag =
True
continue
# 当小小人头部在最顶部时,从上到下扫描时,当x处于小小人位置中时,跳过本次循环
if (role_start_x - 50 <= x <= role_end_x + 50)
and role_top_flag:
# 当x轴坐标在小小人位置时
continue
# 顶部既不是小小人,又与初始像素点不一样,则定位为棋盘顶部,退出x轴扫描
if not is_similar(current_rgb, im_pixel[min_x, min_y],
20):
# 与背景像素点不一样
top_x =
x
# 解决棋盘边上出现一条乱七八糟颜色点将棋盘围起来时的BUG,找到第一个差异点后y轴继续往下5个像素点作为顶点
top_y = y + 4
top_rgb =
im_pixel[top_x, top_y]
break
if top_rgb:
# 找到与初始点不一样的像素点,退出y轴循环
break
top =
(top_x, top_y)
draw.point([top], fill=(255
, 0, 0))
# step3:寻找棋盘最右侧点,条件:从top_x 向右,top_y 向下扫描,当与棋盘顶部像素点相似,x轴最大时,所在点为最右点
right_x =
top_x
right_y =
top_y
find_border =
False
check_rgb =
top_rgb
for x
in range(top_x, max_x):
for y
in range(top_y, max_y):
current_rgb =
im_pixel[x, y]
# 找到相邻的相似元素点,定位条件:30个像素内,颜色相似
if is_similar(current_rgb, check_rgb, 20)
and abs(
x - right_x) <= 5
and abs(y - right_y) <= 5
:
check_rgb =
current_rgb
find_border =
True
right_x =
x
right_y =
y
break
else:
# 如果当前y轴扫描完毕都没有遇到棋盘相似点(即没有遇到break),说明已经超出了最右侧棋盘点,退出x轴循环
if find_border:
break
right =
(right_x, right_y)
draw.point([right], fill=(255
, 0, 0))
# step4:定位棋盘中心:扫描棋盘,判断是否存在中心白点,否则初略可认为棋盘中心点位置是顶点和右侧点交叉位置
border =
(top_x, right_y)
# 先排除初略中心点位置与白色中心点相似的情况,否则遇到白色版面会定位错误
if not is_similar(im_pixel[top_x, right_y], white_point, 4
):
find_white_point =
False
for y
in range(top_y + 5, right_y + 5
):
for x
in range(top_x * 2 - right_x + 5, right_x - 5
):
if is_similar(im_pixel[x, y], white_point, 2
):
# 寻找到白色中心点
find_white_point =
True
border = (x, y + 10
)
print(
"寻找到白色中心点!")
break
# 寻找到白色中心点,退出y轴循环
if find_white_point:
break
draw.point([border], fill=(255
, 0, 0))
# draw.line([top, right], fill=(255, 0, 0), width=10)
draw.line([role, top, right, border], fill=(255, 0, 0), width=10
)
# img.show()
img.save(
"debug.png")
return math.sqrt((role[0] - border[0]) ** 2 + (role[1] - border[1]) ** 2
)
def jump(distance):
press_time = distance *
press_coefficient
press_time = max(press_time, 200)
# 设置 200ms 是最小的按压时间
press_time =
int(press_time)
cmd =
'adb shell input swipe 400 400 400 400 {duration}'.format(
duration=
press_time)
print(cmd)
os.system(cmd)
return press_time
if __name__ ==
'__main__':
i = 1
# img = get_screenshot()
# img=Image.open('autojump.png')
# distance = calculate_jump_distance(img)
# img.close()
# jump(distance)
while True:
img =
get_screenshot()
distance =
calculate_jump_distance(img)
jump(distance)
img.close()
i += 1
if i == 10
:
time.sleep(2
)
time.sleep(2
)
print(
"*" * 100)
***微信扫一扫,关注“python测试开发圈”,了解更多测试教程!***
转载于:https://www.cnblogs.com/guanfuchang/p/8318323.html
相关资源:微信小游戏跳一跳辅助脚本Python源码