本文将以4399小游戏《宠物连连看经典版2》为测试用例,通过识别小图标,模拟鼠标点击,快速完成游戏脚本。
打开浏览器窗口(单个窗口)。游戏主界面截图需要两个坐标(左上角和右下角)来确定。原点一般是屏幕的左上角。不确定坐标点数值的同学可以全屏截图,用图片编辑软件查看坐标值。
获取窗口句柄,这里是浏览器标题栏的标题(右键查看源代码-标题,加上软件名称),例如:“宠物连连看经典2、宠物连连看经典版2游戏、4399游戏www.4399.com-Google Chrome”。抓住窗户把手,你就可以开始了。
总体开发思路:截取游戏主画面——分割成小画面——比较每一个小画面,比较画面的熟悉程度,将数字存入矩阵——连接性计算矩阵——模拟点击。
抓住窗户把手,关上窗户。
Python可以使用win32gui模块调用Windows API来操作窗口,FindWindow()方法可以获得窗口的句柄。需要传入两个参数,第一个是父窗口的句柄(这里填0就行),第二个是窗口的名称(标签标题——Google Chrome)。获取句柄然后通过SetForegroundWindows()将窗口设置在前面,在这里可以发送游戏窗口的报告。代码如下:
抓取游戏界面,拆分图标,对比图片。
在这里检查程序需要一些时间。如果抓拍的画面不好,会影响后续的操作,所以更重要的是确认游戏的左上角和右下角两个坐标值,以及每个小图标的宽度和高度。如下图所示,先截取整个游戏界面图,然后划分小图标,再比较每个图标,然后用数字替换图标,存入矩阵(这里的编号矩阵和游戏图不一致,原理相同)。
根据初始化设置的左上角和右下角两个坐标,使用ImageGrab.grab()方法截图,然后传入一个元组。然后,将大图分割,剪成小图标,存储在images_list数组中。
上面代码剪下的小图标转换成数字矩阵。如果图标已经存储在image_type_list中,将返回该索引。如果不存在,就会追加,然后当前长度就是这个新添加图标的编号。代码如下:
上面的getIndex是对比图片,判断图标是否出现过(是否已经存在于image_type_list中,如果没有出现,则添加)。这里用海明距离来判断两张图片的相识度,阈值设为10。当它小于阈值时,它被认为是相同的图片。具体代码如下:
核心-图标连接算法(路径查找)
这里简单分析一下算法代码。如果对程序理解不太好,可以留言,然后可以做图文分析。
通过以上开发过程,基本得到以下矩阵。只要比较两个相同编号的值,就搜索可连通路径,如果找到,就执行模拟点击操作。这里简单介绍一下游戏的规则:8排12列的游戏图标区域,外围的0其实是表示你可以找到通过它的路径。例如,坐标(1,1)可以与(1,10)、(7,1)和(7,2)连接。
方法的思路:路径搜索的第一步是找到一个可以横向和纵向直接连通的坐标集。比如坐标p1(1,1)的集合有[(0,1),(1,0)],另一个坐标p2(1,10)的可连通集合是[(0,10)],然后进行p1和p2的可连通坐标集合。
代码实现过程简单分析:在isReachable()中传入两个需要比较的坐标值,然后分别得到两个可以水平连接和垂直连接的坐标集(isRowConnect()、isColConnect())。最后遍历集合,比较是否存在连通性,如果存在,则传递的两个坐标可以连通。
学习这样的游戏辅助脚本,对于个人培养编程兴趣也是有帮助的。是工作之余很好的消遣,以后会往这些方向学习。