使用pydirectinput实现《堡垒之夜》鼠标定位玩家名称标签失效问题求助
pydirectinput实现《堡垒之夜》鼠标定位玩家名称标签失效问题求助
问题描述
我希望按下按键后,鼠标能移动到玩家的名称标签位置。在桌面用Windows十字光标测试时是正常的,但在游戏里鼠标会跑到随机位置。我已经尝试了相对移动,但问题还是一样——找到名称标签后,鼠标还是会移到“随机位置”。
我的代码如下:
import pyautogui import pydirectinput import time import keyboard def loop1(): while True: image_files = ["Screenshot 2025-01-25 153403.png"] for filename in image_files: try: center_x, center_y = pyautogui.size() center_x = center_x // 2 center_y = center_y // 2 region = (center_x - 750, center_y - 600, 1500, 1200) nametag = pyautogui.locateCenterOnScreen(filename, confidence=0.6, region=region) if nametag: print("found") x, y = nametag pydirectinput.moveRel(x, y, duration=0.1) print("found file", filename, "in", nametag) time.sleep(1) continue except pyautogui.ImageNotFoundException: time.sleep(2) print('not found') continue time.sleep(1) while True: if keyboard.is_pressed('`'): loop1()
问题原因分析
- 坐标系统完全混淆:这是核心问题!
pyautogui.locateCenterOnScreen返回的是屏幕绝对坐标,但你用了pydirectinput.moveRel(相对当前鼠标位置的偏移量),直接把绝对坐标当相对偏移传进去,鼠标当然会跑到离谱的位置。 - 游戏全屏独占模式的干扰:《堡垒之夜》这类游戏默认用全屏独占模式,系统级鼠标坐标和游戏内部坐标可能存在偏移,同时会屏蔽部分系统级输入模拟的逻辑。
- 图像识别的误判可能:
confidence=0.6的阈值偏低,可能把游戏内相似的UI元素误识别成名称标签,导致“随机移动”的假象。
解决方案
1. 修正坐标逻辑(最关键)
直接把绝对坐标传给绝对移动方法,或者计算正确的相对偏移量:
选项A:改用绝对移动(最简单直接)
把pydirectinput.moveRel(x, y, duration=0.1)替换成:
pydirectinput.moveTo(x, y, duration=0.1)
因为nametag已经是屏幕上的绝对坐标,moveTo会直接把鼠标移到这个点,完全符合你的需求。
选项B:计算正确的相对偏移(如果必须用相对移动)
如果你确实需要基于当前鼠标位置做相对移动,要先获取当前坐标再算偏移:
current_x, current_y = pydirectinput.position() offset_x = x - current_x offset_y = y - current_y pydirectinput.moveRel(offset_x, offset_y, duration=0.1)
2. 适配游戏全屏模式
给pydirectinput添加适配游戏的初始化配置,同时处理高DPI屏幕的坐标偏移:
import ctypes # 解决高DPI屏幕下的坐标缩放问题 ctypes.windll.user32.SetProcessDPIAware() # 调整pydirectinput参数适配游戏输入逻辑 pydirectinput.FAILSAFE = False pydirectinput.PAUSE = 0.01
3. 优化图像识别可靠性
- 把
confidence值提高到0.7-0.8,减少误识别概率 - 确保你的截图是游戏内纯净的名称标签,不要包含周围的UI或背景元素
- 可以先打印
nametag的坐标,和你肉眼看到的名称标签位置对比,确认识别是否准确
修正后的完整代码
import pyautogui import pydirectinput import time import keyboard import ctypes # 适配高DPI屏幕,避免坐标偏移 ctypes.windll.user32.SetProcessDPIAware() # 调整pydirectinput设置适配游戏 pydirectinput.FAILSAFE = False pydirectinput.PAUSE = 0.01 def loop1(): while True: image_files = ["Screenshot 2025-01-25 153403.png"] for filename in image_files: try: center_x, center_y = pyautogui.size() center_x = center_x // 2 center_y = center_y // 2 region = (center_x - 750, center_y - 600, 1500, 1200) nametag = pyautogui.locateCenterOnScreen(filename, confidence=0.7, region=region) if nametag: print("found") x, y = nametag # 改用绝对移动 pydirectinput.moveTo(x, y, duration=0.1) print("found file", filename, "in", nametag) time.sleep(1) continue except pyautogui.ImageNotFoundException: time.sleep(2) print('not found') continue time.sleep(1) while True: if keyboard.is_pressed('`'): loop1()
额外排查建议
- 先以窗口化模式运行游戏测试,排除全屏独占模式的干扰
- 检查
pydirectinput版本,确保是最新版:pip install --upgrade pydirectinput - 可以在游戏里开启“显示鼠标位置”的设置(如果有),对比
nametag的坐标和实际位置是否一致
备注:内容来源于stack exchange,提问作者Ori Tubis
相关产品推荐
相关产品推荐

