You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 15:14:31