Roblox游戏无法识别win32api/pyautogui模拟的鼠标移动,模拟点击失效问题求助
Roblox游戏无法识别win32api/pyautogui模拟的鼠标移动,模拟点击失效问题求助
兄弟,我太懂你这个问题了!Roblox这类游戏的输入检测机制会区分真实物理鼠标移动和API直接模拟的光标跳转,像你用win32api.SetCursorPos或者pyautogui直接移过去的操作,会被它判定为非人类输入,所以按钮不会触发hover效果(变大),点击也无效。下面给你几个亲测有效的解决思路:
1. 模拟真实的鼠标平滑移动,而非瞬间跳转
真实鼠标移动是有轨迹的,不是一下子跳到目标位置。你可以修改你的move函数,让光标逐步移动到目标坐标,每步移动几个像素并加极小延迟,让游戏误以为是真实操作:
def move_smooth(x, y): current_x, current_y = win32api.GetCursorPos() # 计算每步移动的方向 step_x = 1 if x > current_x else -1 if x < current_x else 0 step_y = 1 if y > current_y else -1 if y < current_y else 0 # 逐步移动光标 while current_x != x or current_y != y: if abs(current_x - x) > 0: current_x += step_x if abs(current_y - y) > 0: current_y += step_y win32api.SetCursorPos((current_x, current_y)) sleep(0.001) # 极小延迟,贴近人类移动速度
然后把主循环里的move(x,y)换成move_smooth(x,y)即可。
2. 使用更底层的SendInput替代mouse_event
mouse_event是比较老旧的API,Roblox的检测机制很容易识别它。而SendInput是模拟硬件级别的输入,更难被检测到,我们可以用它来重写移动和点击函数:
首先需要补充一些结构定义(因为SendInput依赖底层数据结构):
import win32api import win32con from ctypes import * # 定义SendInput所需的基础结构 INPUT_MOUSE = 0 MOUSEEVENTF_ABSOLUTE = 0x8000 MOUSEEVENTF_MOVE = 0x0001 MOUSEEVENTF_LEFTDOWN = 0x0002 MOUSEEVENTF_LEFTUP = 0x0004 class INPUT(Structure): _fields_ = [ ("type", c_uint), ("mi", c_ulong * 20) # 简化定义,满足基础使用即可 ] def send_smooth_move(x, y): # 获取当前光标位置 current_x, current_y = win32api.GetCursorPos() # 计算每步移动的步长 step_x = 1 if x > current_x else -1 if x < current_x else 0 step_y = 1 if y > current_y else -1 if y < current_y else 0 # 分多次发送移动事件,模拟平滑轨迹 while current_x != x or current_y != y: if abs(current_x - x) > 0: current_x += step_x if abs(current_y - y) > 0: current_y += step_y # 转换为绝对坐标(0-65535范围,符合SendInput要求) abs_x = current_x * 65535 // win32api.GetSystemMetrics(win32con.SM_CXSCREEN) abs_y = current_y * 65535 // win32api.GetSystemMetrics(win32con.SM_CYSCREEN) input_struct = INPUT() input_struct.type = INPUT_MOUSE input_struct.mi[0] = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE input_struct.mi[1] = abs_x input_struct.mi[2] = abs_y win32api.SendInput(1, byref(input_struct), sizeof(input_struct)) sleep(0.001) def send_click(): # 发送鼠标按下事件 input_down = INPUT() input_down.type = INPUT_MOUSE input_down.mi[0] = MOUSEEVENTF_LEFTDOWN win32api.SendInput(1, byref(input_down), sizeof(input_down)) sleep(0.1) # 发送鼠标抬起事件 input_up = INPUT() input_up.type = INPUT_MOUSE input_up.mi[0] = MOUSEEVENTF_LEFTUP win32api.SendInput(1, byref(input_up), sizeof(input_up))
用这两个函数替换原来的move和click,效果会好很多。
3. 确保Roblox窗口处于激活状态
有时候模拟输入失效是因为焦点不在游戏窗口上,你可以在移动光标前先激活Roblox窗口:
import win32gui def activate_roblox(): # 查找Roblox窗口(标题可能需要根据实际情况调整) hwnd = win32gui.FindWindow(None, "Roblox") if hwnd: win32gui.SetForegroundWindow(hwnd) sleep(0.2) # 给窗口留出激活时间
在主循环里找到按钮坐标后,先调用activate_roblox()再移动光标。
你的原始代码参考
import pyautogui as ag import win32api, win32con from time import sleep import keyboard as kb print(kb._os_keyboard.from_name) def move(x, y): win32api.SetCursorPos((x,y)) def click(): win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0,0) sleep(0.10) win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0,0) while True: sleep(1) res = ag.locateCenterOnScreen("C:/Users/YM/Desktop/python_vscode/tds_autoskip/skip_button.png", confidence=0.8) if res != None: x, y = res print(x,y) move(x,y) sleep(0.5) click() else: print("no find")
备注:内容来源于stack exchange,提问作者Nimbus_Rod
相关产品推荐
相关产品推荐

