如何让基于pyautogui的Python游戏脚本在后台运行?
问题描述
我刚接触编程不久,代码如有不足还请见谅,谢谢。
我为游戏编写了一个执行特定任务的脚本,但该脚本依赖pyautogui和pytesseract,运行时游戏必须处于前台,导致我无法同时使用系统。请问是否有办法让脚本在游戏后台运行,以便我同时使用电脑?
我的代码
import pyautogui pyautogui.FAILSAFE=False import time import keyboard from pyautogui import * import pytesseract as tess from pygame.event import get_grab tess.pytesseract.tesseract_cmd = r'C:\Users\arshi_k8rjg1x\AppData\Local\Tesseract-OCR\tesseract' from PIL import Image, ImageGrab a = input("Name of pokemon:") name="VS. "+"Wild "+a+'\n' b = input("Name of pokemon:") name1="VS. "+"Wild "+b+'\n' c = input("Name of pokemon:") name2="VS. "+"Wild "+c+'\n' time.sleep(3) def movement(): while pyautogui.pixel(1248, 496)[0] != 27 and [1] != 25 and [2] != 27: pyautogui.keyDown('D') time.sleep(0.05) pyautogui.keyUp('D') time.sleep(0.05) pyautogui.keyDown('A') time.sleep(0.05) pyautogui.keyUp('A') img = ImageGrab.grab(bbox=(831, 320, 1100, 350)) text = tess.image_to_string(img) if text == name or text==name1 or text==name2: time.sleep(6) attack() else: pyautogui.keyDown('4') time.sleep(0.5) pyautogui.keyUp('4') time.sleep(2) movement() def attack(): pyautogui.keyDown('1') time.sleep(0.3) pyautogui.keyUp('1') time.sleep(0.3) pyautogui.keyDown('3') time.sleep(0.3) pyautogui.keyUp('3') time.sleep(9) pyautogui.keyDown('3') time.sleep(0.3) pyautogui.keyUp('3') time.sleep(0.3) pyautogui.keyDown('1') pyautogui.keyUp('1') movement() movement()
解决方案
要让脚本在游戏后台运行,核心是替换掉当前依赖前台的几个核心操作,具体可以这么做:
1. 替换全局按键模拟:直接给游戏窗口发按键消息
pyautogui是模拟全局按键,必须前台。改用pywin32直接给目标游戏窗口发送键盘事件,不需要窗口处于激活状态。
- 先通过窗口标题获取游戏窗口的句柄
- 用
SendMessage发送按键按下/抬起的消息
示例代码片段:
import win32gui import win32api import win32con import time # 替换成你的游戏窗口标题 hwnd = win32gui.FindWindow(None, "你的游戏窗口标题") def send_window_key(hwnd, vk_code): # 发送按键按下消息 win32api.SendMessage(hwnd, win32con.WM_KEYDOWN, vk_code, 0) time.sleep(0.05) # 发送按键抬起消息 win32api.SendMessage(hwnd, win32con.WM_KEYUP, vk_code, 0) # 示例:发送D键(对应win32con.VK_D) send_window_key(hwnd, win32con.VK_D)
2. 替换屏幕捕获:只捕获游戏窗口区域
ImageGrab只能捕获前台屏幕,改用mss或pywin32直接捕获游戏窗口的画面,再传给tesseract识别。
示例用mss捕获窗口并识别:
import mss from PIL import Image import win32gui import pytesseract as tess hwnd = win32gui.FindWindow(None, "你的游戏窗口标题") # 获取窗口的全局坐标 left, top, right, bottom = win32gui.GetWindowRect(hwnd) with mss.mss() as sct: # 定义要捕获的窗口区域 monitor = {"top": top, "left": left, "width": right-left, "height": bottom-top} window_img = sct.grab(monitor) # 转换成PIL图像 pil_img = Image.frombytes('RGB', window_img.size, window_img.bgra, 'raw', 'BGRX') # 把原来的全局裁剪坐标转换成窗口相对坐标 crop_area = (831-left, 320-top, 1100-left, 350-top) text = tess.image_to_string(pil_img.crop(crop_area))
3. 替换全局像素检测:获取游戏窗口内指定点的颜色
pyautogui.pixel是取全局坐标的颜色,改用win32gui.GetPixel获取游戏窗口内相对坐标的像素值:
import win32gui def get_window_pixel(hwnd, x, y): dc = win32gui.GetWindowDC(hwnd) color = win32gui.GetPixel(dc, x, y) win32gui.ReleaseDC(hwnd, dc) # 把颜色值转换成RGB格式 r = color & 0xFF g = (color >> 8) & 0xFF b = (color >> 16) & 0xFF return (r, g, b) # 把原来的全局坐标1248,496转换成窗口相对坐标 pixel_color = get_window_pixel(hwnd, 1248-left, 496-top)
注意事项
- 要确保游戏窗口标题正确,不确定的话可以用
win32gui.EnumWindows枚举所有窗口查找 - 部分带反作弊的游戏会拦截窗口消息,这种方法可能失效
- tesseract识别时要注意坐标转换,必须把全局坐标改成窗口内的相对坐标
内容的提问来源于stack exchange,提问作者Arshit Sharma
相关产品推荐
相关产品推荐

