前言
人在美国,刚下飞机,在等行李的时候写下这篇博客,纪念一下我长达两天的踩坑史,以及一种新的思维,面向百度编程,本文介绍的是如何用python做钢琴块脚本,用到模块有
- PIL模块
- numpy模块
- ctypes模块(使用动态链接库)
正文
好,接下来就开始漫长的踩坑史了,Are you ready?
ADB坑
一开始,我想的是在手机上进行触屏操作,还别说,真有这东西
工具包我打包了,点击此处下载 密码:xsx3
放在你的工作目录下(其实可以不用全放的,但是全放肯定没问题) ,手机打开usb 调试,
然后打开ADBDriverInstaller.exe:
点击之后就可以关闭了
进入工作目录,cmd,输入命令:
adb shell
出现一大串参数就代表没问题,
介绍几个会用到的adb命令:
//(保存到SDCard)
adb shell /system/bin/screencap -p /sdcard/screenshot.png
// 从SD卡导出到电脑,注意 F:\\mvp 为电脑路径,必须存在
adb pull /sdcard/screenshot.png F:\\mvp(保存到电脑)
//在(x,y)处模拟点击
adb shell input tap x y
然后在介绍下 PIL模块:
from PIL import Image
import numpy as np
path="" #path为图片路径
img=np.array(Image.open(path))#img为这张图片的三维矩阵[y][x][r,g,b]
如果在某一点的rgb相加小于100,那么它就是可以点击的地方,即为黑色方块。纵坐标固定,横坐标检查四个点对应四列,要不是因为我测试了一下截一张图传到电脑上要两秒,点击一下要一秒,我差点就兴奋了,怎么玩,一次要三秒,开什么玩笑,还不如手玩,果断认同放弃ADB
于是我苦思冥想,痛定思痛,终于灵光一现,有没有一种方法,是可以直接在电脑上操作手机,而不需要向ADB这么慢的呢,很庆幸,答案是有的!!!傲软投屏,满足你的一切需求,支持逆向操作!! 界面如图:
利用鼠标可以模拟手机点击,果断百度python 如何操作鼠标,有一个库是pyhook,刚好满足这种需求,结果我编译器安装失败,百度一看
原文链接https://www.cnblogs.com/nymrli/p/9557023.html
哈哈哈,如果一个钩子算邪恶,那windows API岂不是罪大恶极?该放弃时就要放弃,稍加思索,决定写一个动态链接库来操作鼠标点击,新建一个文件夹命名为Pro1,新建一个文件命名为Click.c放在Pro1文件夹下。Click.c内容如下
#include<windows.h>
#include<stdio.h>
void click(int x,int y){//定义一个方法,传坐标参数
SetCursorPos(x, y);//移动鼠标到(x,y)
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);//鼠标左键点击
}
这里稍微介绍一下mouse_even,原文链接https://blog.csdn.net/THmen/article/details/78249422
然后用gcc 把它编译成动态链接库,步骤如下:
- 打开cmd,进入Pro1目录下
- 输入命令
gcc -m64 -shared Click.c -o Click.dll
//如果python是32位的就用-m32- 回车
然后就发现在你的Pro1目录下有一个Click.dll文件了
如何用这个动态库呢
安装ctypes模块,pycharm界面如下:
来测试一下这个点击的速度吧,在Pro文件夹下新建test.py
from ctypes import *
import _thread #这个模块需要安装
import time
test=CDLL("./Click.dll")
class date:
Count=0 #存储点击次数
def t(name,n):#至少要两个参数,随便填
while True:
test.click(500,500)
date.Count+=1
_thread.start_new_thread(t,("ll",1))
time.sleep(1)#过一秒
print("在一秒钟之内点击了{n}下".format(n=date.Count))
除去加载图片的时间,也绰绰有余了木有,哈哈,很好的开端,为了少走弯路,使数据计算的更简单,我们要耍点聪明,把傲软录屏拖到左上角,如图:
尽量保持手机左上角和电脑屏幕左上角对齐,此时坐标为(0,0),经过测验,右下角坐标为(450,805),数据出来直接上整代码
import numpy as np
from PIL import ImageGrab
from ctypes import *
BOX=(0,699,450,701)
screen=np.array(ImageGrab.grab(BOX)#截取纵坐标从699到701,横坐标为0到450的屏幕区域
click=CDLL("./Click.dll")
def click(x,y):#自定义鼠标点击方法,引用Click动态链接库
click.click(x,y)
def judge(x,y):#判断(x,y)是不是深色像素
sum=int(screen[y][x][0])+int(screen[y][x][1])+int(screen[y][x][2]) #要强转型为int 原型为0~255的类型,这里对(x,y)这个像素点的rgb求和,纯黑为(0,0,0)
if(sum<=100):#如果为深色
return True
return False
while True:
screen=np.array(ImageGrab.grab(BOX)#不断更新选屏区
for n in range(0,4):
if(judge(int(56.25+N*113),1)):#经过不断计算,发现横坐标取这四个点最为合适,纵坐标实际上为699+1
click(45 + 90 * n, 565)#此处进行了单位转换,上面的单位是像素点,这里的我也不知道是什么,数据是经过计算得出的,我用着没事
至此,只能说大概完成了,但是还有bug,当我按下一个黑色方块后,下一帧的时候,我又会接着去按那个按过了的方块,所以要杜绝这种情况的发生,代码修改如下:
import numpy as np
from PIL import ImageGrab
from ctypes import *
BOX=(0,699,450,701)
screen=np.array(ImageGrab.grab(BOX)#截取纵坐标从699到701,横坐标为0到450的屏幕区域
click=CDLL("./Click.dll")
def click(x,y):#自定义鼠标点击方法,引用Click动态链接库
click.click(x,y)
def judge(x,y):#判断(x,y)是不是深色像素
sum=int(screen[y][x][0])+int(screen[y][x][1])+int(screen[y][x][2]) #要强转型为int 原型为0~255的类型,这里对(x,y)这个像素点的rgb求和,纯黑为(0,0,0)
if(sum<=100):#如果为深色
return True
return False
N=-1#上一帧点击了哪一列的方块,初始值为-1
while True:
screen=np.array(ImageGrab.grab(BOX)#不断更新选屏区
for n in range(0,4):
if(judge(int(56.25+N*113),1)):#经过不断计算,发现横坐标取这四个点最为合适,纵坐标实际上为699+1
if(n!=N):#如果上一帧的所在列和现在的不同
N=n#更改N
click(45 + 90 * n, 565)#此处进行了单位转换,上面的单位是像素点,这里的我也不知道是什么,数据是经过计算得出的,我用着没事
到这里,已经差不多了,但是如果万的分数多了,就会出现一个问题,
比如,这一次我点击了第三列,但是我领了金币之后,下一个方块又从第三列下来,那么照它的逻辑,就game over!!了,所以得杜绝,更改如下
import numpy as np
from PIL import ImageGrab
from ctypes import *
BOX=(0,699,450,701)
screen=np.array(ImageGrab.grab(BOX)#截取纵坐标从699到701,横坐标为0到450的屏幕区域
click=CDLL("./Click.dll")
def click(x,y):#自定义鼠标点击方法,引用Click动态链接库
click.click(x,y)
def judge(x,y):#判断(x,y)是不是深色像素
sum=int(screen[y][x][0])+int(screen[y][x][1])+int(screen[y][x][2]) #要强转型为int 原型为0~255的类型,这里对(x,y)这个像素点的rgb求和,纯黑为(0,0,0)
if(sum<=100):#如果为深色
return True
return False
N=-1#上一帧点击了哪一列的方块,初始值为-1
canC=False#是否可以点击
while True:
screen=np.array(ImageGrab.grab(BOX)#不断更新选屏区
for n in range(0,4):
if(judge(int(56.25+N*113),1)):#经过不断计算,发现横坐标取这四个点最为合适,纵坐标实际上为699+1
if(n!=N):#如果上一帧的所在列和现在的不同
N=n#更改N
canC=True
click(45 + 90 * n, 565)#此处进行了单位转换,上面的单位是像素点,这里的我也不知道是什么,数据是经过计算得出的,我用着没事
if (canC):
if(judge(int(56.25+N*113),1)==False ):
N=-1
canC=False
至此,就没什么太大了的问题了,建议运行的时候电脑保持流畅,我最高跑了小星星 1073分
来闲扯两句,其实我不怎么用python的,搭建神经网络的时候用了下python,然后大一下学期的时候左字符串动画用了下,现在快大二了,小专科一个,能活到现在,多亏了度娘,这两天左这个东西,完全就是突发奇想,百度了两天,跑到1000多分的时候我已经兴奋了,本来是想着插上USB,再最后垂死挣扎一下,然后洗洗睡的,结果稍微改了下还跑成功了,差点喜极而泣,谢谢谢谢,已经语无伦次了,如果我这篇博客能帮到你,我会更开心