【python】python制作 连连看 游戏脚本(一)_sunriver2000的博客-CSDN博客

【python】python制作 连连看 游戏脚本(二)_sunriver2000的博客-CSDN博客

【python】python制作 连连看 游戏脚本(三)_sunriver2000的博客-CSDN博客

【python】python制作 连连看 游戏脚本(四)_sunriver2000的博客-CSDN博客

在游戏中学习编程,即享受了游戏的乐趣,有提升了编程能力,可谓一举两得。

本文以【宠物连连看经典版2】为例,讲述使用python制作简单的游戏脚本。

游戏网址:宠物连连看经典版2

代码下载:GitHub - sunriver2000/LinkGameAss

环境

系统:win10 x64

Python版本:V3.6.6

主要模块:win32gui(识别窗口、窗口置顶等操作)、pillow(屏幕截图)、numpy(创建矩阵)、operator(比较值)、pymouse(模拟鼠标点击)。

安装参考:

【Python】安装pyuserinput_sunriver2000的博客-CSDN博客

【Python】安装pillow与numpy_sunriver2000的博客-CSDN博客

1、建立数学模型

【宠物连连看经典版2】游戏目标:需要消除的是8*12的图标矩阵,如下图所示。

实际8*12图标矩阵外围有一圈空白通道,所以实际矩阵规格是10*14,如下图。

空白通道用0表示,图标有12种分别用1至12数字表示,上图可以抽象为如下矩阵。

[[ 0  0  0  0  0  0  0  0  0  0  0  0  0  0][ 0  1  2  3  4  4  5  5  3  1  1  6  7  0][ 0  2  8  9  3  5  1  4  2  8 10  8  5  0][ 0 11  5  2  9 12 10  7  8  9 12  3 11  0][ 0 11  6  6  4  7 11  6 10 11 12  1  3  0][ 0 10  2 11 10  7 12 11  3  9 12 12 10  0][ 0 12  8  7  2  6  8  1 10  7  6  5  8  0][ 0  1  9  9  9  4  4  6  7 11  4  1 10  0][ 0  5  3  5  6  4 12  7  2  9  8  2  3  0][ 0  0  0  0  0  0  0  0  0  0  0  0  0  0]]

A图标通过两次90度拐弯到达B图标,则AB图标消除。消除后,矩阵内原来位置补零,变成通道。

综上,脚本主要涉及图像识别、图标消除等两种算法。

2、初始化

2.1、获取游戏窗口标题

打开【连连看】游戏网页后,使用EnumChildWindows()函数枚举所有窗口并保存为文本文件。浏览文件,确定窗口标题为【宠物连连看经典版2小游戏,在线玩,4399小游戏 - 360极速浏览器 13.5】。

import win32gui, win32ui, win32con, win32api# 打开文件
f = open('winlist.txt', 'w', encoding='utf-8')
#f = open('winlist.txt', 'w')# GetDesktopWindow 获得代表整个屏幕的一个窗口(桌面窗口)句柄
hd = win32gui.GetDesktopWindow()# 获取所有子窗口
hwndChildList = []win32gui.EnumChildWindows(hd, lambda hwnd, param: param.append(hwnd), hwndChildList)for hwnd in hwndChildList:print("句柄:",hwnd,"标题:",win32gui.GetWindowText(hwnd))f.write("句柄:" + str(hwnd) + " 标题:" + win32gui.GetWindowText(hwnd) + '\n')f.close()

以上代码可以独立执行。

2.2、前置游戏窗口

前置游戏窗口的代码放在GameAssist类初始化中,类声明对象后,自动前置游戏窗口。

class GameAssist:def __init__(self, wdname):#初始化# 取得窗口句柄self.hwnd = win32gui.FindWindow(None, wdname)if not self.hwnd:print("can't find window, name is : 【%s】" % wdname)exit()print("find window, name is : 【%s】" % wdname)# 窗口显示最前面win32gui.SetForegroundWindow(self.hwnd)

在主函数中,调用方式如下。

if __name__ == "__main__":wdname = u'宠物连连看经典版2小游戏,在线玩,4399小游戏 - 360极速浏览器 13.5'demo = GameAssist(wdname)

3、图像识别算法

3.1、确定参数

第一个参数是图标矩阵的坐标,包括:左上角和右下角两个点位。

左上角( 360,258)

右下角(1253,853)

获取方法:抓屏,使用画图进行编辑。这两个坐标必须精确,会影响到后续图像识别。

第二个参数是图标的高度(高度与宽度相等)。

width = (1253 - 360)/ 12 = 74.41

    def __init__(self, wdname):#初始化# 取得窗口句柄self.hwnd = win32gui.FindWindow(None, wdname)if not self.hwnd:print("can't find window, name is : 【%s】" % wdname)exit()print("find window, name is : 【%s】" % wdname)# 窗口显示最前面win32gui.SetForegroundWindow(self.hwnd)# 小图标标号矩阵self.im2num_arr = []# 截图的左上角坐标和右下角坐标self.screen_left_and_right_point = (360, 258, 1253, 853)# 小图标宽高self.im_width = 74.41self.mouse = PyMouse()

3.2、截取图标矩阵

def screenshot(self):image = ImageGrab.grab(self.screen_left_and_right_point)save_im(image, 'image')           return image_list

使用ImageGrab.grab()截取屏幕后,可以保存为图片进行调试。

def save_im(image, name):# 创建存储路径screen_path = os.path.join(os.path.dirname(__file__), 'screen')if not os.path.exists(screen_path):os.makedirs(screen_path)# 保存图片到存储路径image_name = os.path.join(screen_path, name)#print("image_name: %", image_name)t = time.strftime('%Y%m%d_%H%M%S', time.localtime())image.save('%s_%s.png' % (image_name, t))  # 文件名name后面加了个时间戳,避免重名

矩阵外围的长方形线宽保留1个像素,效果如下。

3.3、分解为12*8个图标

分解图标后,存入image_list列表中。

    def screenshot(self):image = ImageGrab.grab(self.screen_left_and_right_point)save_im(image, 'image')image_list = {}offset = self.im_widthfor x in range(8):image_list[x] = {}for y in range(12):top = round(x * offset)left = round(y * offset)bottom = round((x + 1) * offset)right = round((y + 1) * offset)im = image.crop((left, top, right, bottom))image_list[x][y] = im#print("top = {}, left = {}".format(top, left))save_im(image_list[x][y], str(x).zfill(2)+str(y).zfill(2)) return image_list

保存为图片,分解效果如下图所示,应该有12*8个,图片没有截全。

3.4、图像数字化

现在已经得到图标图像的列表,但是计算机无法直接对比两个图标是否一致,需要图像数字化。

第一步,彩色转为黑白灰度。

image1 = im1.resize((20, 20), Image.ANTIALIAS).convert("L")

第二步,转为为一串01序列

        # 降灰度图标转成01串,即二进制数据pixels1 = list(image1.getdata())avg1 = sum(pixels1) / len(pixels1)     hash1 = "".join(map(lambda p: "1" if p > avg1 else "0", pixels1))

第三步,对比完成后,存入 image_type_list列表。这里是考验前期参数与算法的地方了,理论上mage_type_list只会存入12个元素。调试时,放开如下代码。

        for i in range(len(image_type_list)):save_im(image_type_list[i], str(i).zfill(2))

涉及函数

     def image2num(self, image_list):# 1、创建全零矩阵和空的一维数组arr = np.zeros((10, 14), dtype=np.int32)image_type_list = []# 2、识别出不同的图片,将图片矩阵转换成数字矩阵for i in range(len(image_list)):for j in range(len(image_list[0])):im = image_list[i][j]# 验证当前图标是否已存入index = self.getIndex(im, image_type_list)# 不存在,则存入image_type_listif index < 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))for i in range(len(image_type_list)):save_im(image_type_list[i], str(i).zfill(2))self.im2num_arr = arrreturn arr# 检查数组中是否有图标,如果有则返回索引def getIndex(self, im, im_list):for i in range(len(im_list)):if self.isMatch(im, im_list[i]):return ireturn -1# 汉明距离判断两个图标是否一样def isMatch(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(lambda p: "1" if p > avg1 else "0", pixels1))hash2 = "".join(map(lambda p: "1" if p > avg2 else "0", pixels2))# 统计两个01串不同数据的个数match = sum(map(operator.ne, hash1, hash2))# 阀值设为10return match < 40

【python】python制作 连连看 游戏脚本(一)相关推荐

  1. 【python】python制作 连连看 游戏脚本(二)

    [python]python制作 连连看 游戏脚本(一)_sunriver2000的博客-CSDN博客 [python]python制作 连连看 游戏脚本(二)_sunriver2000的博客-CSD ...

  2. 【python】python制作 连连看 游戏脚本(三)

    [python]python制作 连连看 游戏脚本(一)_sunriver2000的博客-CSDN博客 [python]python制作 连连看 游戏脚本(二)_sunriver2000的博客-CSD ...

  3. 学会Python就能做游戏脚本开发?别天真了!—— 关于游戏脚本的3个质疑

    现如今想从事和游戏相关的工作,例如游戏开发或游戏脚本策划的伙伴越来越多. 很多想从事脚本开发的伙伴有如下3点质疑: 1.学会Python就可以从事游戏脚本的工作吗? 2.脚本开发只需要学习Python ...

  4. 学会Python就能做游戏脚本开发?别天真了!

    现如今想从事和游戏相关的工作,例如游戏开发或游戏脚本策划的伙伴越来越多. 很多想从事脚本开发的伙伴有如下3点质疑: 1.学会Python就可以从事游戏脚本的工作吗? 2.脚本开发只需要学习Python ...

  5. 用Python可以制作手机游戏吗?

    是的,可以用Python制作手机游戏. Python是一种高级编程语言,可以用来开发多种类型的软件,包括手机游戏.通过使用一些第三方库,比如 Pygame.Kivy.Ren'Py 等,可以方便地制作出 ...

  6. python+大漠插件写游戏脚本

    python+大漠来写个游戏脚本 安装anaconda 安装32位python环境 使用大漠插件来进行辅助开发 安装anaconda anaconda是开源的,通过官网直接下载,网速差的也可以通过清华 ...

  7. python能制作游戏吗_什么用Python让制作的游戏角色移动起来?

    Python是完全面向对象的语言.函数.模块.数字.字符串都是对象.并且完全支持继承.重载.派生.多继承,有益于增强源代码的复用性. 在本系列的第四部分,学习如何编写移动游戏角色的控制代码. 在这个系 ...

  8. Python实践 制作石头剪刀布游戏 带GUI界面

    一.开发需求 使用 Python 编程实现 "石头剪刀布" 游戏,具体要求如下: 程序随机"出拳":在屏幕上显示"石头","剪刀& ...

  9. java制作安卓游戏脚本_autoA开源(用java写安卓无障碍脚本)

    类 ScreenLib类 封装了模糊找色,屏幕点击,屏幕滑动等方法. TsFrame抽象类 封装了脚本的逻辑流程(帮助你快速开发脚本) Fa和Fb 都是继承自F,他们大部分方法都是一样的.重新封装了屏 ...

最新文章

  1. 中国AI服务器,刷新全球18项性能基准测试纪录
  2. Android 干货,强烈推荐
  3. 使用VS开发C++ 控制台程序或其他项目出现 ‘ LINK : fatal error LNK1104: 无法打开文件“LIBCD.lib” ’ 常规解决办法
  4. 做mysql服务器 需要什么配置最好_支持大型数据库的服务器需要什么配置
  5. 我想在杭州买一套房一百平米左右的房子大概多少钱?
  6. HDU1265 Floating Point Presentation【水题】
  7. 代码帝:一个月10万行代码
  8. 如何把DEBIAN变成UBUNTU-DESKTOP最少化安装
  9. [深度学习项目] - 时间序列预测 (2)
  10. python登录豆瓣_手把手教你用python模拟登录豆瓣
  11. 物联网新零售项目 新零售制胜之道
  12. 园区3D可视化三维展示系统解决方案
  13. 信创培训第一课:linux操作系统基础
  14. 视频太大,如何把视频压缩到最小
  15. 显著性检验【t-test、方差分析、ks检验】
  16. android tun0 流量统计,Android应用流量统计——NetworkStatsManager使用-Go语言中文社区...
  17. GZIPOutputStream GZIPInputStream 数据压缩解压
  18. 新型多功能、高性能量子点,可以用于医学成像、量子计算
  19. svchost.exe占用过高CPU和内存的解决方案
  20. JWT如何解析过期的token中的信息

热门文章

  1. 一篇文章带你走近Android自定义view
  2. cogs 944. [東方S3] 藤原妹红
  3. Gimp图像处理资料收集
  4. 购物网站商城系统,购物网站毕业设计,B2C网上购物系统毕业设计
  5. SystemVerilog学习-10-验证量化和覆盖率
  6. 3ds模拟JAVA游戏_3ds模拟器Citra3ds下载
  7. mysql创建序列发生器_字符控制发生器可以干啥
  8. MySQL完美卸载-奇怪的小知识
  9. 笔记本高分辨软件兼容问题,字体太小或模糊
  10. 4分用计算机算,4分制绩点换算(4分制绩点计算器)