[初学python]利用Win32API实现鼠标自动点击

python 同时被 2 个专栏收录
12 篇文章 0 订阅
116 篇文章 0 订阅

python在Windows系统下可以调用win32 api来实现一些系统级的功能,比如控制鼠标和键盘来实现游戏辅助。

但是python并没有自带这些库文件,需要自己动手安装pywin32这个库,安装方法:pip install pywin32

今天就以Flash小游戏彩色砖块为实验对象,用python写一个自动点击的“游戏外挂”。

彩色砖块这个小游戏在很多年前出现在QQ空间3366小游戏。

一共200个方块,在规定时间内,点击空白区域,消除相同颜色的方块越多得分越高,满分200分。

那时候为了和QQ好友比赛,比分数高,就用C++写了一个辅助小程序,完成了200分。

今天为了学习python,再次找到它,把Flash文件下载到本地电脑,用独立的Flash播放器打开这个block.swf文件。

swf文件可以在我的网盘下载:http://446252221.ys168.com/   (文件路径:FLASH/block.swf)

代码思路和用C语言一样:

1.利用GetPixel函数,获取所有方块的颜色,保存到列表,

2.然后遍历所有的空白点,判断这个空白点的上下左右4个方向有没有相同颜色的方块,

3.如果有则调用SetCursorPos和mouse_event模拟鼠标点击,

4.重复第2,3步,直到所有空白区域都判断完毕。

 

注意事项:

需要事先分析方块的颜色值,游戏区域的坐标,以及方块的大小。

 

下面开始写代码:

#FLASH小游戏彩色砖块辅助工具
#以下参数需要调整
#窗口大小: 668 * 526
#游戏区大小: 660 * 499
#第一次点击开始:(330, 425)
#第二次点击开始:(320, 280)
#左上角第一个方块相对坐标: (60, 100)
#格子大小: 25 * 25
#格子数量: 23 * 15
#空白格子颜色: 0xF7F7F7 和 0xEDEDED
#实体格子颜色: 
#0x0066cc
#0x00cc00
#0x6666ff
#0xbbbbbb
#0xcccc66
#0x66cccc
#0xcc66cc
#0xff6600
#0xff88ff
#0x0099ff

import time
import win32gui
import win32ui
import win32api
import win32con

#查找游戏窗口,返回窗口起始坐标
def find_flash_window():
    hwnd = win32gui.FindWindow("ShockwaveFlash", "Adobe Flash Player 28")
    if(hwnd):
        rect = win32gui.GetWindowRect(hwnd)
        return rect[0],rect[1]
    return None

#模拟鼠标点击
def mouse_click(x, y):
    win32api.SetCursorPos([x, y])
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
    
#点击格子
def click_block(xbase, ybase, x, y):
    x = xbase + x * 25 + 60
    y = ybase + y * 25 + 100
    mouse_click(x, y)


#颜色转换为方块类型
def convert_color_to_type(color):
    if(color == 0x0066cc):
        return 0x01
    if(color == 0x00cc00):
        return 0x02
    if(color == 0x6666ff):
        return 0x03
    if(color == 0xbbbbbb):
        return 0x04
    if(color == 0xcccc66):
        return 0x05
    if(color == 0x66cccc):
        return 0x06
    if(color == 0xcc66cc):
        return 0x07
    if(color == 0xff6600):
        return 0x08
    if(color == 0xff88ff):
        return 0x09
    if(color == 0x0099ff):
        return 0x0A
    if(color == 0xededed):
        return 0x00
    if(color == 0xf7f7f7):
        return 0x00
    return 0xFF
    
    
#获取方块类型
def load_one_block(hdc, xbase, ybase, x, y):
    x = x * 25 + xbase + 60;
    y = y * 25 + ybase + 100;
    color = win32gui.GetPixel(hdc, x, y)
    return convert_color_to_type(color)
    
#获取所有方块 
def load_all_block(map, xbase, ybase):
    hdc = win32gui.GetWindowDC(0)
    map.clear()
    for y in range(0, 14):
        list = []
        for x in range(0, 22):
            type = load_one_block(hdc, xbase, ybase, x, y)
            list.append(type)
        map.append(list)
    win32gui.ReleaseDC(hdc, 0)
    
#返回指定格子左边的方块
def find_left_block(map, x, y):
    for i in range(0, x):
        if(map[y][x - i] != 0x00):
            return map[y][x - i]
    return 0xFF
    
#返回指定格子右边的方块
def find_right_block(map, x, y):
    for i in range(x, 22):
        if(map[y][i] != 0x00):
            return map[y][i]
    return 0xFF

#返回指定格子上边的方块
def find_top_block(map, x, y):
    for i in range(0, y):
        if(map[y - i][x] != 0x00):
            return map[y - i][x]
    return 0xFF
    
#返回指定格子下边的方块
def find_bottom_block(map, x, y):
    for i in range(y, 14):
        if(map[i][x] != 0x00):
            return map[i][x]
    return 0xFF
    
#判断这个格子是否可以点击
def is_block_clickable(map, x, y):
    if(map[y][x] != 0) or (map[y][x] != 0):
        return False
    left = find_left_block(map, x, y)
    right = find_right_block(map, x, y)
    top = find_top_block(map, x, y)
    bottom = find_bottom_block(map, x, y)
    
    if(top == bottom) and (top != 0xFF):
        print("t = b:", top, bottom)
        return True
    if(top == left) and (top != 0xFF):
        print("t = l:", top, left)
        return True
    if(top == right) and (top != 0xFF):
        print("t = r:", top, right)
        return True
    if(left == right) and (left != 0xFF):
        print("l = r:", left, right)
        return True
    if(left == bottom) and (left != 0xFF):
        print("l = b:", left, bottom)
        return True
    if(right == bottom) and (right != 0xFF):
        print("r = b:", right, bottom)
        return True
    return False
    
#查找可以点击的格子
def find_click_block(map):
    for x in range(0, 22):
        for y in range(0, 14):
            if(is_block_clickable(map, x, y)):
                return x,y
    return None

def dump_all_block(map):
    for y in range(0, 14):
        for x in range(0, 22):
            print("%02X " % (map[y][x]), end="")
        print()
        
#程序入口
map = []
xbase = 0
ybase = 0
print("正在查找游戏窗口...")
pos = find_flash_window()
if(pos == None):
    print("查找游戏窗口失败!")
    exit()
print("查找游戏窗口成功.")
xbase = pos[0]
ybase = pos[1]
while(True):
    load_all_block(map, xbase, ybase)
    dump_all_block(map)
    print("正在查找可以点击的格子")
    pos = find_click_block(map)
    if(pos == None):
        print("游戏结束!")
        exit()
    print(pos)
    click_block(xbase, ybase, pos[0], pos[1])
    time.sleep(1)

 

  • 6
    点赞
  • 0
    评论
  • 37
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值