欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

用python玩微信跳一跳游戏

程序员文章站 2024-03-18 13:49:04
...

前言

本篇博客介绍了如何使用python代码玩微信跳一跳游戏。很早之前就听说过使用python脚本玩跳一跳游戏刷分,当时对相关原理一窍不通,但这完全不影响我的好奇心和求知欲。如今终于有机会探求其中的奥妙。

百度上一搜python、跳一跳关键词,就弹出不知多少相关教程。但我发现很多代码用的方法似乎有一定缺陷,在遇到一些情况时就无法起作用了。而这些情况在游戏过程中不可避免的会出现,这就导致最终的分数可能并不会很高。

本篇博客综合多方面的idea,主要参考此源码(下提到此源码一词,即指代此处),基于自己的理解做了一些修改和简化。原文中分别给出了在 Android 和 iOS 下运行的代码,和多种不同思路的方法。此处仅介绍Android下的一种方法。


环境配置要求

  1. 安装python3

  2. 安装ADB,并设置好环境变量,确保在CMD中adb命令可识别。安装完后插入安卓设备,且打开USB调试模式,在终端中输入: adb devices. 显示类似如下表明设备已连接

List of devices attached
6934dc33 device
  1. 安装其他依赖库:opencv, numpy

代码实现

分析

  1. 在本项目中,adb工具的作用是将游戏截图发送到电脑端、模拟手指按压使棋子跳跃。adb工具的使用在本项目中不起关键作用,即使不了解adb工具也可完成本项目。(博主就完全不了解adb命令)
  2. 电脑依据游戏截图,识别棋子所处位置和下一步落点中心位置(称棋盘),计算两者距离,再计算按压时间。最后执行相应的adb命令,手机端棋子即会进行跳跃。

显然,本项目的关键点有三个:

  1. 识别棋子所处位置
  2. 识别棋盘中心位置
  3. 计算按压时间

识别棋子所处位置

我使用的方法是利用opencv中的模板匹配函数cv2.matchTemlpate(),只需要提供一张棋子的图像即可,准确度非常高。左一图为棋子图像,左二图为识别结果。

用python玩微信跳一跳游戏

棋子位置已经有了,但我们要的是棋子所处的坐标点。取方框X方向的中点为X坐标,取方框Y方向 9/10 处为Y坐标。棋子所处的坐标点就是(X, Y),如右一图。

识别棋盘中心位置

这部分比较复杂,我参照了此源码的实现方法,但二者又有明显不同。

据观察,我们认为,在Y方向上(竖直方向)棋盘出现的位置在1/3 - 2/3处之间。而在X方向上(水平方向),如果棋子在屏幕偏左方,棋盘必在棋子的右方;如果棋子在屏幕偏右方,棋盘必在棋子的左方。那么我们搜索的范围就大大缩小,如下图红框(此时棋子在屏幕偏左方):

用python玩微信跳一跳游戏

寻找上顶点

我们先找到棋盘的上顶点。

显然,棋盘上顶点颜色与背景色差异较大,可依据这一特点在区域内搜索。从红框左上角像素开始逐行搜索,取每行最左端点为初始点记录像素值,与该行内的每个像素进行比对,如果二者差异较大,就认为找到了上顶点。

为提高搜索速度,可以每50行取一行搜索,如果出现差异较大的点,在重新搜索这50行,取第一个差异点为上顶点。

这种方法在棋盘是菱形时是有效的,但棋盘是椭圆形时是否有效呢?你可能认为也有效,因为椭圆形也只具有一个上顶点。实际上,我发现椭圆形棋盘在截图中没有上顶点,最上面是一条短线(把截图放大也能发现)。因此,在用上面的方法时,得到的上顶点会是这条短线的最左端的点。

用python玩微信跳一跳游戏

上面的方法是,在行内找到一个差异点就终止搜索,认为这个差异点是上顶点。我们修改一下,在行内找差异点后继续搜索该行,并记录差异点,知道该行搜索完毕终止搜索。把记录的所有差异点的取平均值,就能得到短线的中点,即椭圆的上顶点。

寻找中心点

好了,我们找到棋盘的上顶点了,无论它是椭圆形还是菱形,结果都是准确的。

但如何寻找棋盘的中心点?我也不知道。起初我的想法是,找到棋盘的上顶点和右端点,二者分别做个辅助线交点就是棋盘中心点了。于是我用类似寻找上顶点的方法,寻找右端点,从右向左逐列搜索,没错是找到了。但我发现,少部分情况下会出问题。当棋盘位于屏幕偏右方,结果完全准确;当棋盘位于屏幕偏左方,因为我们限制了搜索范围(只搜索棋子的左方),结果大部分情况下也是准确的。什么时候不准确呢?当棋子和棋盘靠的很近,而棋盘又比较大的时候,棋盘的右端点被棋子遮住了…这我还搜索个啥?虽然这种情况很少出现,但不得不说他不是种好方法。

用python玩微信跳一跳游戏

那搜索棋盘左端点行不行?也不行。当棋盘位于屏幕偏右方,棋盘左端点也有被遮住的可能。

这个时候,此源码使用的方法就比较高端,出现上述情况时也能准确计算出中心点。下面我讲解一下。

得到了棋盘的上顶点坐标,它的X坐标就是棋盘中心点的X坐标,那么只要计算出Y坐标。我理解这位牛人的意思应该是,游戏有一个对称中心,并且该对称中心到棋盘中心的连线与水平方向的夹角是固定的。你可能认为对称中心是屏幕的中点,但这位牛人是这样计算的:

center_x = w / 2 + (24 / screen_width) * w
center_y = h / 2 + (17 / screen_height) * h

给出的角度是tan θ = 25.5 / 43.5 。

咋来的?不知道,真不知道。算了,先用吧。

既然知道了这个规律,那么我们就可以这样计算出棋盘中心点的坐标(X, Y ):

用python玩微信跳一跳游戏
这种规律到底是不是存在的?我们可以验证一下,下面是我调试代码时得到的一些图像:

用python玩微信跳一跳游戏

仅用肉眼来看的话,我们几乎可以认为两个棋盘中心点的连线是平行的(此时棋子处于中心点)。而大量事实也证明了,牛人给出的规律是有效的,计算出的中心点位置很准确。

计算按压时间

好了,我们终于得到了棋子起始坐标点、棋盘中心点坐标,那么就可以计算出二者的直线距离了。然后根据直线距离,计算按压时间。

说实话,这位大牛计算按压时间的代码,我实在没看懂…不过我猜测,也许是考虑不同手机屏幕分辨率适配等等问题。大家有兴趣可以看一下。

我就比较粗暴,勾股定理计算直线距离,直线距离乘以时间系数等于按压时间(我这种方法的效果似乎也不差)。这里的时间系数,是大牛源码里提到的。似乎是不同屏幕大小的手机时间系数略有不同,此源码里已经给了配置文件,我也在我的源码里放了,略微做了些修改。


最终效果

最终效果比较依赖于配置文件中的数据,尤其是按压时间系数,大家可以根据自己的实际情况进行修改。

我的手机是Huawei nova 2s,屏幕大小是2160x1080,实际分数随随便便能够达到三四千分,最后一次游戏的分数是8000多分。欢迎大家在评论区晒出自己的分数哦!

用python玩微信跳一跳游戏

源码奉上

GitHub


使用说明

  1. 安卓手机通过数据线与电脑相连,打开手机的USB调试
  2. 电脑端执行adb devices,确保手机已连接
  3. config 文件夹下有对应于手机分辨率的配置文件。可以将config.json文件复制到项目根目录下,代码会优先读取;也可不复制,代码自动在config文件夹下搜索匹配的配置文件;实际效果不好时,可手动调整配置文件。
  4. 手机界面切换到微信跳一跳游戏,点击开始游戏
  5. 执行python wechat_jump_auto.py

总结

特别鸣谢这位大牛,没有ta本篇博客无法顺利完成。本篇博客是博主基于自身理解写成,难免出现错误,望各位批评指正。无论是建议、想法和疑问,各位皆可在评论区提出,集思广益,互帮互助。

欢迎访问我的个人博客