Python实战之跳一跳

早先考试忙于学业,今天终于抽出时间整理一下Python之跳一跳项目。废话不多说,直接进入正题。

准备工作:

1. Python

2. adb驱动

我就不分享环境配置了,毕竟配置环境是玄学。

整体解决思路:

跳一跳的玩法是距离决定按压时间。那么计算距离就是需要突破的难点了,计算出距离之后乘以一个系数就是按压时间了。可以截一张手机屏幕,将图片上拉到电脑,计算距离,然后通过adb调试工具给手机下发指令,按压一定时间,等跳跃稳定,再上拉图片,计算距离,下发指令,依次循环。

计算距离思路:

找到下一个要跳跃的小格中心坐标,找到棋子中心坐标,计算距离。

首先要把这个图片处理为矩阵,这样就是一个数学问题了。该数组是包含了RGB信息的彩色图像矩阵。例如一个小格颜色为白色,则该小格RGB值为[255,255,255],我的手机分辨率为1920*1080,那么就一共有1920*1080个这样的小格。通过比较每一小格RGB值,找到棋子中心和下一个小块中心是解决该问题的核心。

1.如何找到方块的中心?

遍历每一行每一列的RGB值,找到突变的位置。首先确定行值,然后确定当前行第一个像素格的RGB,然后遍历每一列并与第一个像素格的RGB比较,如有较大改变,则为突变位置。记录行值和列值,观察发现方块中心和该顶点在同一列。那么中心的纵坐标已经得到。再此基础上,确定列值,继续遍历每一行,找到最下方顶点,两个顶点取平均就是终点坐标了。

顶点放大示意图

2.如何计算棋子中心坐标?

因棋子颜色不变,因此求棋子坐标较为简单,同样采用遍历方式。通过工具得到棋子中心的RGB值为[92,55,52],只需要找到该像素值,那这个小格就是中心点。

不上代码的分享都是耍流氓,代码比较粗糙,结构未采用子函数格式,这样可能存在冗余,结构不清晰,但是这样简洁易懂啊~~

importcv2

importnumpyasnp

fromskimageimportio,transform

importos

importtime

img = cv2.imread('C:\python\screen1.png')

matrix = np.asarray(img)

# print(matrix.shape)

#初始化

r=92

b=52

g=55

ybegin=

findflag=

dangflag=

#找到方块中心

forxinrange(600,1920):

iffindflag==1:

break

first0 = matrix[x][][]

first1 = matrix[x][][1]

first2 = matrix[x][][2]

foryinrange(,1000):

ifdangflag ==1:

ify>ybegin-40andy

continue

ifabs(int(matrix[x][y][])-int(first0)) +abs(int(matrix[x][y][1])-first1)

+abs(int(matrix[x][y][2])-first2)>15:

ifabs(int(matrix[x][y][1]) -53) +abs(int(matrix[x][y][]) -59)

+abs(int(matrix[x][y][2]) -52)

# 如果是棋子,重新寻找

print('被挡住了!!')

ybegin =y

dangflag=1

break

xbegin=x

value0=matrix[x+3][y][]

value1=matrix[x+3][y][1]

value2=matrix[x+3][y][2]

pointy=y

findflag=1

break

forindex1inrange(,300):

index=xbegin+300-index1

ifabs(int(matrix[index][y][])-int(value0))

-int(value1))

xend=index

pointx=(int(xbegin)+int(xend))/2

print('中点:'+str(pointx)+' '+str(pointy))

break

#找到棋子中心

qiziflag=

forqizixinrange(200,1920):

index2=1919-qizix

ifqiziflag==1:

break

forqiziyinrange(,1080):

ifabs(int(matrix[index2][qiziy][1])-g)

qizixbegin=index2-15

qiziy=qiziy+20

qiziflag=1

print('棋子坐标:'+str(qizixbegin)+' '+str(qiziy))

break

distance=np.sqrt(pow(qizixbegin-pointx,2)+pow(qiziy-pointy,2))

print('距离:'+str(distance))

计算结果为:

验证结果:

由下图得(截图中x,y坐标与程序计算颠倒):

下一块方块中心:(849.7,789.4)

棋子中心:(1116.5,338.6)

由此可见,计算正确,误差较小。

然后添加adb工具,将以上代码写成循环即可一直跳下去了~~

  • 发表于:
  • 原文链接:http://kuaibao.qq.com/s/20180125G0C2VW00?refer=cp_1026

扫码关注云+社区