2013-01-23 16 views
17

Ich versuche, ein Spiel zu steuern (meine beiden Testspiele sind Half Life 2 und Minecraft) mit meiner Kinect und Python. Alles funktioniert bis auf eine Sache. Das Spiel reagiert auf simulierte Mausereignisse und simulierte Mausbewegungen (Mausereignisse werden über ctypes ausgeführt und Mausbewegungen werden mit pywin32 durchgeführt). Das Problem ist jedoch, dass die Spiele simulierte Tastendrücke ignorieren. Beide nehmen die simulierten Tastenanschläge entweder im Chatfenster (Minecraft) oder in der Entwicklerkonsole (Half Life 2) auf, aber nicht während des eigentlichen Spiels.Simulieren Sie Python-Tasten zum Steuern eines Spiels

Ich habe die Tastenanschläge des Sendens mehrere Möglichkeiten versucht:

import win32com.client as client 
wsh = client.Dispatch('WScript.Shell') 
wsh.AppActivate(gameName) 
wsh.SendKeys(key) 

und:

import win32api 
win32api.keybd_event(keyHexCode, 0, 0) 

und:

import ctypes 
import time 

SendInput = ctypes.windll.user32.SendInput 

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

ich den Code in das letzte möchte darauf hinweisen, ist nicht meins, es ist eine andere Frage hier auf Stack Overflow.

Weiß jemand, warum keiner von diesen funktioniert und was der richtige Weg ist, dies zu tun?

+1

Anstelle einer richtigen Antwort, könnte ich die Quelle von Minecraft empfiehlt zu überprüfen, ob es einen Unterschied in ist, wie Tastatur-Ereignisse werden gesammelt und behandelt zwischen dem Chat und Gameplay? Ich werde es mir selbst ansehen, wenn ich nach Hause komme. – Logan

+0

Ich muss meine frühere Aussage darüber zurückziehen, dass sie mit Minecraft nicht funktioniert, mit dem Ctypes-System. Ich überprüfe Half Life 2 jetzt noch einmal ... – user573949

+0

Ja, es funktioniert immer noch nicht. – user573949

Antwort

3

Es ist wahrscheinlich, dass das Spiel DirectInput-Geräte verwendet.

Also, das Spiel erwartet DirectInput Tasten drücken. Laut dem letzten Beitrag von this forum thread reagiert DirectInput auf ScanCodes, nicht auf VKs. Sie können versuchen, DirectInput-Tasten mit this tool zu senden. Der Entwickler liefert auch die Quelle und eine detaillierte Erklärung.

Wenn das funktioniert, können Sie einfach versuchen, entsprechende ScanCodes anstelle von VKs (list of scancodes) zu senden.

Es gibt auch ein älteres Projekt namens DirectPython, mit dem Sie eine Schnittstelle mit DirectX/DirectInput erstellen können.

+0

Der Download-Link für dieses Tool ist tot, wissen Sie, wie DirectInput-Tastenkombinationen mit DirectPython tatsächlich gesendet werden? Es scheint nur darauf ausgerichtet zu sein, auf sie zu hören, sie nicht zu versenden. – user573949

19

Ich hatte gerade das gleiche Problem beim Versuch, Key-Prints in Half-Life 2 zu simulieren. Wie Robin sagte, ist die Lösung, ScanCodes anstelle von VKs zu verwenden.

Ich habe Ihr letztes Codebeispiel so bearbeitet, dass es ScanCodes verwendet. Ich versuchte es mit Half-Life 2 und es funktioniert gut:

import ctypes 
import time 

SendInput = ctypes.windll.user32.SendInput 

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

# directx scan codes http://www.gamespp.com/directx/directInputKeyboardScanCodes.html 
while (True): 
    PressKey(0x11) 
    time.sleep(1) 
    ReleaseKey(0x11) 
    time.sleep(1) 
Verwandte Themen