刚开始学习Python,萌新总有一颗渴望做实践享受成就感的心,最近“跳一跳”比较火,在看了一些前辈的辅助程序教程后,我就也想写一个自己版本的辅助(for Android)。
写辅助程序的起因就是这样啦,我觉得写“跳一跳”的辅助比玩“跳一跳”更有趣,所以对于那些被辅助程序伤到的“跳一跳”玩家,我表达一下歉意~
另外也希望把我的思路分享给大家,代码挂在这里,供大家各取所需,自娱自乐~
下面就聊一聊这个程序的细节啦,首先是实现原理,萌新版本的原理当然很简单啦。由于很多的知识不太懂(比如os库、Image库、ADB操作等),不懂的部分我就试着套教程、或者照搬别人的轮子。我主要借鉴的是 @霍雍 在下面这篇文章里的程序结构,只是修改了其中的算法。
程序中最主要的部分都集中在“jump_one函数”(基本是copy了@霍雍 的部分),每一次跳跃的实现主要分为五个步骤:
def jump_one(filename):
os.system('adb shell screencap ' + phonePath + filename) #第一步
os.system('adb pull ' + phonePath + filename + " " + imgPath + filename) #第二步
os.system('adb shell rm ' + phonePath + filename) #第三步
swipetime = timecalculate(filename) #第四步
os.system('adb shell input swipe 300 1500 300 1500 ' + str(swipetime)) #第五步
time.sleep(1)
return swipetime
第一步,通过ADB截屏,命名为x.png,存储到手机
第二步,通过ADB将x.png从手机复制到电脑
第三步,通过ADB删除手机上的x.png
第四步,根据filename调用对应命名的截图,计算触摸时间
第五步,根据所算时间,通过ADB执行原位滑屏操作
容易看到,五步中有四步是通过os.system()函数控制ADB完成的(导致效率不高,时间都花在ADB操作上...T-T),比较简单就略过了,核心部分在时间计算上。
PS:我称跳动的小人为“棋子(chessman)”,下一个落脚的物体为“棋盘(chessboard)”。
时间计算 → 距离计算 → △X计算
有个隐藏信息是,触摸时间与跳跃距离成正比,因此我们算出需要跳跃的距离,就能得到时间。
另一个隐藏信息是,跳跃方向都是斜着的,但倾斜角度“基本是”固定的(实际有少许偏移),因此我们只需计算 △X 或者 △Y 即可。
最后一个隐藏信息是,游戏初始时的“棋子”和“棋盘”位置总是固定的,因此可以反复测试初始游戏时的 触摸时间init_time 与 距离init_X 的关系,得到这个常数比值K后,后续计算就简单了:
△T = △X * K = △X * (init_x / init_time)
△X计算 → 找特征像素的坐标
如何找“棋子”与“棋盘”的△X 呢?我看到的帖子,大家有用像素识别的,有用深度学习图像识别的,有用OpenCV提取图像边缘再识别的......我......我...我会的少,只能用笨办法的“像素识别”了...
即找到“棋子”左上角的第一个像素(x, y),再计算该行属于“棋子”像素的个数n,从而X = x + n//2,即可得到“棋子”的横坐标 X 啦,“棋盘”同理。原理示意图如下:
找特征像素的坐标 → 像素识别
识别利用的特征包括:“棋子”顶部像素颜色稳定,亮度较低,与背景像素色差较大;“棋盘”顶部像素颜色不稳定、亮度不稳定,但亮度一定比“棋子”高,且与背景像素有一定色差(并且总与“棋子”的第一像素保持一定距离,用于寻找位置较为靠近的“棋盘”)。
利用上述特征,for循环逐个对截图像素进行判断,即可筛选出特征像素啦,效果如下:
从结果来看,识别的成功率还不错~然并卵,并不能保证“棋子”不跑偏,我觉得可能的原因包括像素识别误差的累积(比如并非所有“棋盘”的中心都在其顶点的正下方,如“硬盘”物体)、ADB操作的延迟等等。
大家可以看到“棋子”逐渐越跳越偏的过程,其原因就在于存在细小偏差,不能保证每次都落在中心这就意味着,棋子容易“中心 → 中心 → 中心”连中多元,也容易“歪一点 → 再歪一点 → 扑街”。不过,“棋子”其实并非是沿固定方向跳跃,而是以“棋子”中心与下一个“棋盘”中心构成的直线的方向跳跃,视情况这种偏差可能会相互抵消,回到正轨。(暂时无图...)
在上述本征不稳定性的基础上呢,大家可能需要多试几次才能拿到理想的分数,测试大概平均能拿到1000+,基本上1000~3000问题不大,我最高拿过3179。
程序的效率并太高,优化后平均跳一次需要4.5~5s,经过测试,约4s的时间花在ADB的操作上了...
...┐(‘~`;)┌ ...
如果开发个APP,所有操作都在手机上进行会不会快一些...
使用说明:
我用Python3写的,在Windows 7上测试跑得很欢,Linux上没有试。
由于使用了ADB工具,所以是针对Android手机的,手机需要打开“USB调试”,电脑端需要安装好手机驱动(或者让手机助手如豌豆荚连一下手机,再退出豌豆荚)。
建议打开cmd命令行,用“cd”命令,进入ADB工具所在路径,输入“adb”,检测adb是否正常使用。
运行.py文件前,建议用IDE打开,调整一下基本参数(在程序最下面):
- 预期跳多少步,默认70
- 分辨率,默认1440 * 2560 (for Samsung S6)
- init_x,经过我的测试,填607 (for 1440 * 2560)或455 (for 1080 * 1920, 1080p),效果比较好,默认607
- init_time,经过我和 @霍雍 各自测试,最后不约而同认为723比较好,默认723
- phonePath,手机上临时存储截图的路径,建议新建一个,默认/storage/emulated/0/test/
- imgPath,电脑端存储截图的路径,建议新建一个,默认C:\Users\Administrator\test\
开始游戏:
- 手机连接电脑,可能有“是否允许该计算机调试”之类的弹窗,点允许调试。
- 手机进入“跳一跳”界面后,电脑端运行.py文件即可。
运行.py文件的方式有两种,用Python的IDE打开并执行;或者用cmd命令执行“python + .py文件的路径”指令,如:
python c:\users\administrator\test\wechathop.py
也可以在cmd窗口输入:"python"+“ ”(空格),
然后把wechathop.py文件拖入cmd窗口,按回车执行即可。
萌新上路,胆大粗心,很多代码写法以及程序使用方法上不严谨、不标准,本程序也仅供娱乐,请其他萌新们谨慎参考,大佬们多指导~~