如何在锁定鼠标的全屏游戏中记录鼠标移动绘制后坐控制轨迹?
解决方案:追踪全屏游戏中的鼠标相对移动轨迹
问题根源
全屏FPS游戏会锁定鼠标光标在屏幕中心,同时使用原始输入(Raw Input)处理鼠标移动,此时系统不会更新鼠标的绝对屏幕坐标,导致你原来通过winput获取的event.position始终是中心位置,无法反映实际的鼠标移动。你需要获取鼠标的相对位移增量(X/Y方向的移动变化值),而非绝对坐标。
可行方案
方案1:使用pynput库(简单易用)
pynput库支持监听鼠标的相对移动事件,即使光标被锁定也能获取到X/Y轴的位移变化,适合快速实现需求。
安装依赖
pip install pynput
示例代码
from pynput import mouse import time # 存储轨迹数据:[(时间戳, X位移, Y位移), ...] trajectory = [] is_recording = False start_timestamp = 0 last_x, last_y = mouse.Controller().position def on_click(x, y, button, pressed): global is_recording, start_timestamp if pressed: is_recording = True start_timestamp = time.time() trajectory.clear() print("开始记录后坐轨迹...") else: is_recording = False print("轨迹记录完成,数据如下:") for entry in trajectory: elapsed_time = entry[0] - start_timestamp print(f"时间: {elapsed_time:.3f}s | 位移: ({entry[1]}, {entry[2]})") # 此处可调用你的可视化逻辑处理trajectory数据 def on_move(x, y): global last_x, last_y if is_recording: dx = x - last_x dy = y - last_y last_x = x last_y = y trajectory.append((time.time(), dx, dy)) # 启动监听器 with mouse.Listener(on_click=on_click, on_move=on_move) as listener: print("按ESC退出,按下左键开始记录轨迹...") listener.join()
方案2:调用Windows Raw Input API(底层精确)
如果需要更底层的控制,直接使用Windows的Raw Input API(通过pywin32库),可以直接读取鼠标的原始移动数据,不受任何游戏的输入拦截影响。
安装依赖
pip install pywin32
示例代码(简化版)
import win32api import win32con import win32gui import time # 注册Raw Input鼠标设备 def register_raw_mouse_input(): hwnd = win32gui.GetForegroundWindow() raw_device = win32api.RAWINPUTDEVICE() raw_device.usUsagePage = 0x01 raw_device.usUsage = 0x02 # 指定为鼠标设备 raw_device.dwFlags = win32con.RIDEV_INPUTSINK raw_device.hwndTarget = hwnd win32api.RegisterRawInputDevices([raw_device]) trajectory = [] is_recording = False start_timestamp = 0 def process_raw_input(msg): global is_recording, start_timestamp if msg.message == win32con.WM_INPUT: raw_data = win32api.GetRawInputData(msg.lParam, win32con.RID_INPUT) if raw_data: input_info = raw_data[0] if input_info.header.dwType == win32con.RIM_TYPEMOUSE: mouse_data = input_info.data.mouse dx = mouse_data.lLastX dy = mouse_data.lLastY # 检测左键按下/释放状态 if mouse_data.usButtonFlags & win32con.RI_MOUSE_LEFT_BUTTON_DOWN: is_recording = True start_timestamp = time.time() trajectory.clear() print("开始记录轨迹...") elif mouse_data.usButtonFlags & win32con.RI_MOUSE_LEFT_BUTTON_UP: is_recording = False print("轨迹记录完成:") for entry in trajectory: elapsed_time = entry[0] - start_timestamp print(f"时间: {elapsed_time:.3f}s | 位移: ({entry[1]}, {entry[2]})") # 记录有效位移 if is_recording and (dx != 0 or dy != 0): trajectory.append((time.time(), dx, dy)) # 注册设备 register_raw_mouse_input() # 消息循环 print("按ESC退出,按下左键记录后坐轨迹...") while True: msg = win32gui.GetMessage(None, 0, 0) if msg[0] == win32con.WM_QUIT: break # 检测ESC键退出 if msg[1].message == win32con.WM_KEYDOWN and msg[1].wParam == win32con.VK_ESCAPE: break process_raw_input(msg[1]) win32gui.TranslateMessage(msg[1]) win32gui.DispatchMessage(msg[1])
关键说明
两种方案均以获取鼠标相对位移增量为核心,即使游戏锁定光标在屏幕中心,也能准确记录你控制鼠标的移动轨迹。你可以将记录的trajectory数据传入可视化模块,通过累加位移还原完整的后坐控制路径。
内容的提问来源于stack exchange,提问作者Arrow Assassin
相关产品推荐
相关产品推荐

