游戏中Python鼠标运动的仿真

14ifxucb  于 2023-01-29  发布在  Python
关注(0)|答案(3)|浏览(174)

我正在考虑使用Kinect玩视频游戏。这需要同时模拟键盘和鼠标事件。我发现键盘事件和ctypes的SendInput()在Skyrim和Minecraft中都可以工作。我还发现ctypes的mouse_event()在Skyrim和Minecraft中都可以模拟鼠标按钮。这些是我目前找到的似乎对Skyrim和Minecraft都有效的解决方案。
我遇到的主要问题是如何在Skyrim中移动玩家的摄像头,我可以使用ctypes的SetUserPos在Minecraft中移动摄像头()以及ctype的鼠标事件()。但这两种解决方案都不适用于Skyrim。我也尝试过使用SendInput()在天际中移动玩家的摄像头,但每次使用SendInput移动光标时()(即使在天际之外)我的显示器一片空白,相机仍然不动(我不知道为什么会发生这样的事情...)
所以,有没有可能在Skyrim或其他类似处理鼠标输入的游戏中模拟摄像机的移动?我愿意使用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()
chhkpiq4

chhkpiq41#

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

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

在Windows的幕后,它会生成类似于您正在使用的ctypes代码,因此它可能会在Skyrim这样的游戏中控制摄像头。
PyAutoGUI可以在Windows、Mac、Linux以及Python 2和Python 3上运行,它还可以模拟键盘、拖动鼠标、截图以及对截图进行简单的图像识别

w51jfk4q

w51jfk4q2#

我已经修复了你的代码,它在win10中为我工作。请查看更改并尝试。
这将相对于当前位置移动光标

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, 0, ctypes.pointer(extra))
    cmd = Input(ctypes.c_ulong(0), ii_)
    ctypes.windll.user32.SendInput(1, ctypes.pointer(cmd), ctypes.sizeof(cmd))

def main():
    #mouse = Mouse()
    MoveMouse(1,15)
    time.sleep(3)
    MoveMouse(1,-15)
    time.sleep(3)
    MoveMouse(1,15)
    time.sleep(3)
    MoveMouse(2,15)

main()

但也可以使用ctypes.windll.user32.SetCursorPos(x,y)直接移动到像素位置。
此操作将光标移动到屏幕上x/y轴上的像素位置

import ctypes

# Move cursor to x 500 and y 500
ctypes.windll.user32.SetCursorPos(500,500)
1hdlvixo

1hdlvixo3#

import ctypes

            SendInput = ctypes.windll.user32.SendInput

            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 Input_I(ctypes.Union):
                _fields_ = [("ki", KeyBdInput),
                            ("mi", MouseInput),
                            ("hi", HardwareInput)]

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

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

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

            def MoveMouse(x, y):
                x = 1 + int(x * 65536./1440.) # <-- monitor 1440x900
                y = 1 + int(y * 65536./900.)
                extra = ctypes.c_ulong(0)
                ii_ = Input_I()
                ii_.mi = MouseInput(x, y, 0, (0x0001 | 0x8000), 0, ctypes.pointer(extra))
                cmd = Input(ctypes.c_ulong(0), ii_)
                ctypes.windll.user32.SendInput(1, ctypes.pointer(cmd), ctypes.sizeof(cmd))

            def LeftClick():
                extra = ctypes.c_ulong(0)
                ii_ = Input_I()
                ii_.mi = MouseInput(0, 0, 0, 0x0002, 0, ctypes.pointer(extra))
                cmd = Input(ctypes.c_ulong(0), ii_)
                ctypes.windll.user32.SendInput(1, ctypes.pointer(cmd), ctypes.sizeof(cmd))

            def LeftRelease():
                extra = ctypes.c_ulong(0)
                ii_ = Input_I()
                ii_.mi = MouseInput(0, 0, 0, 0x0004, 0, ctypes.pointer(extra))
                cmd = Input(ctypes.c_ulong(0), ii_)
                ctypes.windll.user32.SendInput(1, ctypes.pointer(cmd), ctypes.sizeof(cmd))

相关问题