问题描述
我正在尝试编写一个脚本,该脚本会在用户单击鼠标后调整游戏中的视图,并在释放鼠标后停止调整。为了启用/禁用我的脚本,我使用了 keyboard.Listener
中的 pynput
。要知道用户何时单击鼠标,我尝试使用 mouse.Listener
,但它给我带来了一些问题,所以我切换到 pyWinhook.Hookmanager
,我可以使用键绑定来挂钩/取消挂钩。
def left_down(event):
move(10,-10,10,0.15)
return True
hm = pyWinhook.HookManager()
hm.SubscribeMouseLeftDown(left_down)
def on_key_press(key):
if (key==keyboard.Key.f8):
try:
global hm
hm.HookMouse()
except MyException as e:
print('Exception: '.format(e.args[0]))
elif (key==keyboard.Key.f9):
hm.UnhookMouse()
elif (key==keyboard.Key.f10):
hm.UnhookMouse()
key_listener.stop()
with keyboard.Listener(on_press=on_key_press) as key_listener:
key_listener.join()
一切正常,直到我尝试使用模拟游戏中鼠标移动的代码来实现它。据我了解,钩子管理器在调用使用 win32api
PUL = ctypes.POINTER(ctypes.c_ulong)
class KeyBdInput(ctypes.Structure):
_fields_ = [("wVk",ctypes.c_ushort),("wScan",("dwFlags",ctypes.c_ulong),("time",("dwExtraInfo",PUL)]
class HardwareInput(ctypes.Structure):
_fields_ = [("uMsg",("wParamL",ctypes.c_short),("wParamH",ctypes.c_ushort)]
class MouseInput(ctypes.Structure):
_fields_ = [("dx",ctypes.c_long),("dy",("mouseData",PUL)]
class Input_I(ctypes.Union):
_fields_ = [("ki",KeyBdInput),("mi",MouseInput),("hi",HardwareInput)]
class Input(ctypes.Structure):
_fields_ = [("type",("ii",Input_I)]
def move(steps,x=None,y=None,duration=0.25,vertical=False):
x = int(x)
y = int(y)
coordinates = _interpolate_mouse_movement(
start_windows_coordinates=(0,0),end_windows_coordinates=(x,y)
)
for x,y in coordinates:
if (vertical):
x = 0
extra = ctypes.c_ulong(0)
ii_ = Input_I()
ii_.mi = MouseInput(x,y,0x0001,ctypes.pointer(extra))
x = Input(ctypes.c_ulong(0),ii_)
ctypes.windll.user32.sendinput(1,ctypes.pointer(x),ctypes.sizeof(x))
time.sleep(duration / len(coordinates))
def _to_windows_coordinates(x=0,y=0):
display_width = win32api.GetSystemMetrics(0)
display_height = win32api.GetSystemMetrics(1)
windows_x = (x * 65535) // display_width
windows_y = (y * 65535) // display_height
return windows_x,windows_y
def _interpolate_mouse_movement(start_windows_coordinates,end_windows_coordinates,steps=10):
x_coordinates = [start_windows_coordinates[0],end_windows_coordinates[0]]
y_coordinates = [start_windows_coordinates[1],end_windows_coordinates[1]]
if x_coordinates[0] == x_coordinates[1]:
x_coordinates[1] += 1
if y_coordinates[0] == y_coordinates[1]:
y_coordinates[1] += 1
interpolation_func = scipy.interpolate.interp1d(x_coordinates,y_coordinates)
intermediate_x_coordinates = np.linspace(start_windows_coordinates[0],end_windows_coordinates[0],steps + 1)[1:]
coordinates = list(map(lambda x: (int(round(x)),int(interpolation_func(x))),intermediate_x_coordinates))
return coordinates
另一个问题是,我不知道如何创建一个功能,如果只在按下鼠标时应用给定的一系列移动,当鼠标松开时,整个周期应该重置。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)