游戏中的Python鼠标移动仿真

时间:2014-12-28 08:31:03

标签: python python-3.x ctypes emulation sendinput

我正在考虑使用Kinect玩视频游戏。这需要模拟键盘和鼠标事件。我已经发现键盘事件与ctypes' SendInput()适用于Skyrim和Minecraft。我也发现了ctypes' mouse_event()适用于Skyrim和Minecraft,用于模拟鼠标按钮。这些是我迄今为止发现的解决方案,它们似乎适用于“天际”和“我的世界”。

我遇到的主要问题是在天际内移动播放器的相机。我可以使用ctypes'在Minecraft中移动相机。 SetUserPos()和ctypes' mouse_event()。但这两种解决方案都不适用于天际。我也尝试使用SendInput()在天际中移动播放器的相机,但每次光标移动时,SendInput()(甚至在天际之外)我的显示器会空白片刻和相机仍然没有动(我不知道为什么会发生这样的事情......)

那么无论如何我可以在天际或其他可能同样处理鼠标输入的游戏中模仿相机移动吗?我愿意使用C / C ++来完成这项任务,但是直接的Python会更优选。感谢您提出的所有建议!

我还要留下用于使显示器空白的代码。我认为SendInput()可能不会在Skyrim中为相机移动工作,但也许我只是做了一些非常错误的事情。 (我也从网上的大量线程中获得了以下大部分代码。)

import ctypes
import time

# C struct redefinitions
PUL = ctypes.POINTER(ctypes.c_ulong)

class KeyBdInput(ctypes.Structure):
    _fields_ = [("wVk", ctypes.c_ushort),
                ("wScan", ctypes.c_ushort),
                ("dwFlags", ctypes.c_ulong),
                ("time", ctypes.c_ulong),
                ("dwExtraInfo", PUL)]


class HardwareInput(ctypes.Structure):
    _fields_ = [("uMsg", ctypes.c_ulong),
                ("wParamL", ctypes.c_short),
                ("wParamH", ctypes.c_ushort)]


class MouseInput(ctypes.Structure):
    _fields_ = [("dx", ctypes.c_long),
                ("dy", ctypes.c_long),
                ("mouseData", ctypes.c_ulong),
                ("dwFlags", ctypes.c_ulong),
                ("time", ctypes.c_ulong),
                ("dwExtraInfo", PUL)]


class POINT(ctypes.Structure):
        _fields_ = [("x", ctypes.c_ulong),
                    ("y", ctypes.c_ulong)]


class Input_I(ctypes.Union):
    _fields_ = [("ki", KeyBdInput),
                 ("mi", MouseInput),
                 ("hi", HardwareInput)]


class Input(ctypes.Structure):
    _fields_ = [("type", ctypes.c_ulong),
                ("ii", Input_I)]

# Actuals Functions


def PressKey(hexKeyCode):
    extra = ctypes.c_ulong(0)
    ii_ = Input_I()
    ii_.ki = KeyBdInput(0, hexKeyCode, 0x0008, 0, ctypes.pointer(extra))
    x = Input(ctypes.c_ulong(1), ii_)
    ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))


def ReleaseKey(hexKeyCode):
    extra = ctypes.c_ulong(0)
    ii_ = Input_I()
    ii_.ki = KeyBdInput(0, hexKeyCode, 0x0008 | 0x0002, 0, ctypes.pointer(extra))  # lint:ok
    x = Input(ctypes.c_ulong(1), ii_)
    ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))

def MoveMouse(x, y):
    extra = ctypes.c_ulong(0)
    ii_ = Input_I()
    x = int(x*(65536/ctypes.windll.user32.GetSystemMetrics(0))+1)
    y = int(y*(65536/ctypes.windll.user32.GetSystemMetrics(1))+1)
    ii_.mi = MouseInput(x, y, 0, 0x0001 | 0x8000, 1, ctypes.pointer(extra))
    x = Input(ctypes.c_ulong(0), ii_)
    ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))

def main():
    mouse = Mouse()
    time.sleep(3)
    MoveMouse(100, 100)

main()

1 个答案:

答案 0 :(得分:1)

您可以从PyPI安装PyAutoGUI GUI自动化模块(运行pip install pyautogui),然后调用pyautogui.moveTo()点击屏幕的某个X和Y坐标:

>>> import pyautogui
>>> pyautogui.moveTo(50, 100)

在Windows的幕后,它会使用类似的ctypes代码,因此它可能会像Skyrim这样的游戏中控制相机。

PyAutoGUI适用于Windows,Mac和Linux,以及Python 2和3.它还可以模拟键盘,执行鼠标拖动,截取屏幕截图以及对屏幕截图进行简单的图像识别。完整文档位于https://pyautogui.readthedocs.org/