python游戏辅助脚本,完整思路分享


一、表明

详述:责任编辑将以4399小格斗游戏《 狗狗特集经典之作版2 》做为试验事例,透过辨识调色板,演示滑鼠点选,加速顺利完成张佩佩。对有兴趣自学格斗游戏JAVA的老师有很大的协助。

运转自然环境:Win10/Python3.5。

主要就组件:win32gui(辨识询问处、询问处首页等操作方式)、PIL(屏幕截图)、numpy(建立行列式)、operator(较为值)、pymouse(演示滑鼠点选)。

特别注意点:

1、假如加装pymouse不获得成功或是运转收起,能考量先透过whl 加装pyHook、接着再透过pip加装pyuserinput。

2、假如收起 [ImportError: No module named windows ],能修正__init__.py适当的行 为 windows => pymouse.windows。

责任编辑主要就参照:https://baijiahao.baidu.com/s?id=1618385402903335091&wfr=spider&for=pc。

二、合作开发发展前景

格斗游戏远距JAVA在现阶段自然环境也称得上较为盛行了,对时常玩格斗游戏人而言,适度的格斗游戏远距还是很有协助的,让计算机系统做许多繁杂无趣的操作方式。总之除了更为矮小上的其它操作方式,这儿就不约勒了。对格斗游戏远距JAVA,能想不到基本上有下列三种:其一加载格斗游戏在缓存中的统计数据,平庸不然能努力做到更动格斗游戏许多基本上特性,基本原理和许多的BUG或补齐格斗游戏类似于;并有演示使用者使用者犯罪行为,演示滑鼠点选、按键操作方式等。中国狗狗网petji.cn

总之,由于生前未曾牵涉格斗游戏远距JAVA这一领域,出于个人兴趣,自学研究一下,责任编辑例子则是第二种,主要就还是演示使用者犯罪行为,让程序代替使用者操作方式。

三、合作开发流程

先看看程序运转图吧:

浏览器打开格斗游戏询问处(单个一个询问处),格斗游戏界面如下图所示,格斗游戏主要就界面截图需要两个坐标(左上角坐标和右下角坐标)来确定,原点一般是屏幕左上角,不确定坐标点值的老师,能全屏截图,用编辑图片软件查看坐标值。获取询问处句柄,这儿就是浏览器标题栏的标题了(右键-查看源代码-title,加上软件名)比如:狗狗特集经典之作2,狗狗特集经典之作版2小格斗游戏,4399小格斗游戏 www.4399.com - Google Chrome。获取询问处句柄就能开始了。

总体合作开发路子:截取格斗游戏主图 ---> 分割成小图 ---> 对比每个小图,对比图片相识度,编号存入行列式 ---> 对行列式进行可连计算 ---> 演示点选。

3.1、获取询问处句柄,把询问处首页中国狗狗网petji.cn

python能使用win32gui组件调用Windows API实现对询问处的操作方式,使用FindWindow()方法能获取询问处的句柄(handle),需要传入两个参数,第一个为父询问处句柄(这儿填0即可),第二个参数是询问处的名称(标签title - Google Chrome)。获取句柄之后接着透过SetForegroundWindows() 设置询问处在前面,这儿传入格斗游戏询问处的举报即可,代码如下:

3. 2、截取格斗游戏界面,分割图标,图片较为

这儿需要花费许多时间来校验程序,假如截取的图片不好,则会影响后续操作方式,所以较为主要就的是确认格斗游戏左上角和右下角这两个坐标值,以及每个调色板的宽高。

如下图所示,先截取整个格斗游戏界面图,接着分割调色板,接着对每个图标进行较为,接着以编号代替图标存入行列式(这儿的编号行列式和格斗游戏图不一致,基本原理一样)。

根据初始化设定的左上角和右下角两个坐标,使用ImageGrab.grab()方法进行截图,传入一个元组即可,接着对这个大图进行分割,切割成一个个调色板存入到images_list数组中。

透过上面代码切割的调色板,转成数字行列式,假如图标已经存入image_type_list则返回这个索引,假如不存在,则在追加进去,接着现阶段长度就是这个新加入图标的编号,代码如下所示:中国狗狗网petji.cn

上面的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的可连坐标集合进行较为,假如集合中坐标也有可连,则表示p1和p2可连,很明显,(0,1)和(0,10)为同一行且可连,这样就表示p1和p2两点存在可连路径了,代码如下所示:中国狗狗网petji.cn

简单分析下代码实现过程:在isReachable()传入两个需要较为的坐标值,接着分别获取两个点横竖向(isRowConnect()、isColConnect())能连接的坐标集合,最后再对集合进行遍历较为是否存在可连的,假如存在则表示传入的两个坐标是能连接的。

五、合作开发总结

自学这样一个格斗游戏远距JAVA,对个人培养编程兴趣也是有许多协助的,在工作之余不失为一个好的消遣方式,以后会多向这些方向研究自学。本事例仅仅是截图、较为图片和演示滑鼠点选,我觉得还能更为强大,而且还不局限于格斗游戏这样一个领域,相信大家应该见过自动发QQ消息的软件吧,我觉得这完全能做。除了许多演示操作方式能实现:滑鼠滚轮,左右键、按键输入等。

六、附件-源码

特别注意:源码仅供自学,转发注明出处,谢谢!

中国狗狗网petji.cn-*- coding:utf-8 -*-importwin32guiimporttimefromPILimportImageGrab, ImageimportnumpyasnpimportoperatorfrompymouseimportPyMouseclassGameAssist:def__init__(self, wdname):"""初始化"""取得询问处句柄self.hwnd = win32gui.FindWindow(0, wdname)ifnotself.hwnd:print("询问处找不到,请确认询问处句柄名称:【%s】"% wdname )exit()询问处显示最前面win32gui.SetForegroundWindow(self.hwnd)调色板编号行列式self.im2num_arr = []主截图的左上角坐标和右下角坐标self.scree_left_and_right_point = (299,251,768,564)调色板宽高self.im_width =39PyMouse对象,滑鼠点选self.mouse = PyMouse()defscreenshot(self):"""屏幕截图"""1、用grab函数截图,参数为左上角和右下角左标image = ImageGrab.grab((417, 257, 885, 569))image = ImageGrab.grab(self.scree_left_and_right_point)2、分切小图exit()image_list = {}offset = self.im_width398行12列forxinrange(8):image_list[x] = {}foryinrange(12):print("show",x, y)exit()top = x * offsetleft = y * offsetright = (y +1) * offsetbottom = (x +1) * offset用crop函数切割成调色板,参数为图标的左上角和右下角左边im = image.crop((left, top, right, bottom))将切割好的图标存入对应的位置image_list[x][y] = imreturnimage_listdefimage2num(self, image_list):"""将图标行列式转换成数字行列式"""1、建立全零行列式和空的一维数组arr = np.zeros((10,14), dtype=np.int32)以数字代替图片image_type_list = []2、辨识出不同的图片,将图片行列式转换成数字行列式foriinrange(len(image_list)):forjinrange(len(image_list[0])):im = image_list[i][j]验证现阶段图标是否已存入index = self.getIndex(im, image_type_list)不存在image_type_listifindex <0:image_type_list.append(im)arr[i +1][j +1] = len(image_type_list)else:arr[i +1][j +1] = index +1print("图标数:", len(image_type_list))self.im2num_arr = arrreturnarr检查数组中是否有图标,假如有则返回索引下表defgetIndex(self,im, im_list):foriinrange(len(im_list)):ifself.isMatch(im, im_list[i]):returnireturn-1汉明距离判断两个图标是否一样defisMatch(self, im1, im2):缩调色板,转成灰度image1 = im1.resize((20,20), Image.ANTIALIAS).convert("L")image2 = im2.resize((20,20), Image.ANTIALIAS).convert("L")将灰度图标转成01串,即系二进制统计数据pixels1 = list(image1.getdata())pixels2 = list(image2.getdata())avg1 = sum(pixels1) / len(pixels1)avg2 = sum(pixels2) / len(pixels2)hash1 ="".join(map(lambdap:"1"ifp > avg1else"0", pixels1))hash2 ="".join(map(lambdap:"1"ifp > avg2else"0", pixels2))统计两个01串不同数字的个数match = sum(map(operator.ne, hash1, hash2))阀值设为10returnmatch <10判断行列式是否全为0defisAllZero(self, arr):foriinrange(1,9):forjinrange(1,13):ifarr[i][j] !=0:returnFalsereturnTrue是否为同行或同列且可连defisReachable(self, x1, y1, x2, y2):1、先判断值是否相同ifself.im2num_arr[x1][y1] != self.im2num_arr[x2][y2]:returnFalse1、分别获取两个坐标同行或同列可连的坐标数组list1 = self.getDirectConnectList(x1, y1)list2 = self.getDirectConnectList(x2, y2)print(x1, y1, list1)print(x2, y2, list2)exit()2、较为坐标数组中是否可连forx1, y1inlist1:forx2, y2inlist2:ifself.isDirectConnect(x1, y1, x2, y2):returnTruereturnFalse获取同行或同列可连的坐标数组defgetDirectConnectList(self, x, y):plist = []forpxinrange(0,10):forpyinrange(0,14):获取同行或同列且为0的坐标ifself.im2num_arr[px][py] ==0andself.isDirectConnect(x, y, px, py):plist.append([px, py])returnplist是否为同行或同列且可连defisDirectConnect(self, x1, y1, x2, y2):1、位置完全相同ifx1 == x2andy1 == y2:returnFalse2、行列都不同的ifx1 != x2andy1 != y2:returnFalse3、同行ifx1 == x2andself.isRowConnect(x1, y1, y2):returnTrue4、同列ify1 == y2andself.isColConnect(y1, x1, x2):returnTruereturnFalse判断同行是否可连defisRowConnect(self, x, y1, y2):minY = min(y1, y2)maxY = max(y1, y2)相邻直接可连ifmaxY - minY ==1:returnTrue判断两个坐标之间是否全为0fory0inrange(minY +1, maxY):ifself.im2num_arr[x][y0] !=0:returnFalsereturnTrue判断同列是否可连defisColConnect(self, y, x1, x2):minX = min(x1, x2)maxX = max(x1, x2)相邻直接可连ifmaxX - minX ==1:returnTrue判断两个坐标之间是否全为0forx0inrange(minX +1, maxX):ifself.im2num_arr[x0][y] !=0:returnFalsereturnTrue点选事件并设置数组为0defclickAndSetZero(self, x1, y1, x2, y2):print("click", x1, y1, x2, y2)(299, 251, 768, 564)基本原理:左上角图标中点 + 偏移量p1_x = int(self.scree_left_and_right_point[0] + (y1 -1)*self.im_width + (self.im_width /2))p1_y = int(self.scree_left_and_right_point[1] + (x1 -1)*self.im_width + (self.im_width /2))p2_x = int(self.scree_left_and_right_point[0] + (y2 -1)*self.im_width + (self.im_width /2))p2_y = int(self.scree_left_and_right_point[1] + (x2 -1)*self.im_width + (self.im_width /2))time.sleep(0.2)self.mouse.click(p1_x, p1_y)time.sleep(0.2)self.mouse.click(p2_x, p2_y)设置行列式值为0self.im2num_arr[x1][y1] =0self.im2num_arr[x2][y2] =0print("消除:(%d, %d) (%d, %d)"% (x1, y1, x2, y2))exit()程序入口、控制中心defstart(self):1、先截取格斗游戏区域大图,接着分切每个小图image_list = self.screenshot()2、辨识调色板,收集编号self.image2num(image_list)print(self.im2num_arr)3、遍历查找能相连的坐标whilenotself.isAllZero(self.im2num_arr):forx1inrange(1,9):fory1inrange(1,13):ifself.im2num_arr[x1][y1] ==0:continueforx2inrange(1,9):fory2inrange(1,13):跳过为0 或是同一个ifself.im2num_arr[x2][y2] ==0or(x1 == x2andy1 == y2):continueifself.isReachable(x1, y1, x2, y2):self.clickAndSetZero(x1, y1, x2, y2)if__name__ =="__main__":wdname 为特集询问处的名称,必须写完备wdname =u狗狗特集经典之作版2,狗狗特集经典之作版2小格斗游戏,4399小格斗游戏 www.4399.com - Google Chromedemo = GameAssist(wdname)demo.start()GameAssist.py

推荐阅读中国狗狗网petji.cn点选标题可跳转

中国狗狗网:www.petji.cn

如何实现手机远程控制电脑中国狗狗网petji.cn

京东自杀式物流向上海运送物资,如何评价?中国狗狗网petji.cn

python 绘图集锦(小猪佩奇、哆啦A梦、小黄人、皮卡丘、几何图形、、表情、表白、樱花、圣诞树、蛋糕、气球等)中国狗狗网petji.cn

读研、考研热门专业分析,避开内卷中国狗狗网petji.cn

知名大学25岁男博士生,状告女副教授强迫其发生性关系!校方回应!

远程探查室友的网页访问记录

电脑技巧:Win10系统无线投屏

Django 框架合作开发教程A

Django 框架合作开发教程B中国狗狗网petji.cn

Python函数使用详情介绍,建议收藏

如何用Python自动发送邮件?

Python实现自动出牌,挑战欢乐斗地主,帮你赢欢乐豆!!!

Python实现中文字幕雨源代码

Adobe 全系列软件合集,附带教程

Python函数使用详情介绍,建议收藏

python爬取腾讯视频电影

python自学资料大全

闲鱼被曝光暗藏情色交易,实在想不到!!

互联网大厂花式裁员!毕业了?

Python办公自动化之Excel最全整理,实现自动化办公,干货!!

抖音seo行列式系统:www.a8jiaoyi.com

爬取今日热点、各大网站热搜,附视频效果及教

文章整理于互联网,侵删,文章投搞商务合作请加客服微信:9872659

分享到