python 模拟键盘输入 自制游戏手柄

模拟程序

# direct inputs
# source to this solution and code:
# http://stackoverflow.com/questions/14489013/simulate-python-keypresses-for-controlling-a-game
# http://www.gamespp.com/directx/directInputKeyboardScanCodes.html

import ctypes
import time

SendInput = ctypes.windll.user32.SendInput


W = 0x11
A = 0x1E
S = 0x1F
D = 0x20
Z = 0x2c
X = 0x2d
G = 0x22
NP_2 = 0x50
NP_4 = 0x4B
NP_6 = 0x4D
NP_8 = 0x48

# 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))

if __name__ == '__main__':
    PressKey(0x11)
    time.sleep(1)
    ReleaseKey(0x11)
    time.sleep(1)

案例:

通过串口控制键盘输入

import serial
import time
from directkeys import ReleaseKey,PressKey,Z,X,G
ser = serial.Serial('COM5',     115200,timeout=0.01 )#,parity=serial.PARITY_EVEN, rtscts=1
ser.close()
ser.open()
a =  (6,5,4,3,2,1)
for i in a:
    time.sleep(1)
    print(i)

while True:
    s = ser.read(3)
    if len(s)>2:
        ss = s
        print(ss)
        if ss[0] == 49:
            ReleaseKey(Z)
            #print("W松开")
        if ss[0] == 48:
            PressKey(Z)
            #print("W按下")
        if ss[1] == 49:
            ReleaseKey(X)
            #print("X松开")
        if ss[1] == 48:
            PressKey(X)
            #print("X按下")
        if ss[2] == 49:
            ReleaseKey(G)
            #print("G松开")
        if ss[2] == 48:
            PressKey(G)
            #print("G按下")
            

附录:

键盘码https://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html

Ordinary scancodes

The scancodes in translated scancode set 2 are given in hex. Between parentheses the keycap on a US keyboard. The scancodes are given in order, grouped according to groups of keys that are usually found next to each other.

00 is normally an error code

01 (Esc)

02 (1!), 03 (2@), 04 (3#), 05 (4$), 06 (5%E), 07 (6^), 08 (7&), 09 (8*), 0a (9(), 0b (0)), 0c (-_), 0d (=+), 0e (Backspace)

0f (Tab), 10 (Q), 11 (W), 12 (E), 13 ®, 14 (T), 15 (Y), 16 (U), 17 (I), 18 (O), 19 §, 1a ([{), 1b (]})

1c (Enter)

1d (LCtrl)

1e (A), 1f (S), 20 (D), 21 (F), 22 (G), 23 (H), 24 (J), 25 (K), 26 (L), 27 ( : ; ), 28 (’ ") 29 (` ~)

2a (LShift)

2b (|), on a 102-key keyboard

2c (Z), 2d (X), 2e ©, 2f (V), 30 (B), 31 (N), 32 (M), 33 (,<), 34 (.>), 35 (/?), 36 (RShift)

37 (Keypad-) or (/PrtScn) on a 83/84-key keyboard

38 (LAlt), 39 (Space bar),

3a (CapsLock)

3b (F1), 3c (F2), 3d (F3), 3e (F4), 3f (F5), 40 (F6), 41 (F7), 42 (F8), 43 (F9), 44 (F10)

45 (NumLock)

46 (ScrollLock)

47 (Keypad-7/Home), 48 (Keypad-8/Up), 49 (Keypad-9/PgUp)

4a (Keypad–)

4b (Keypad-4/Left), 4c (Keypad-5), 4d (Keypad-6/Right), 4e (Keypad-+)

4f (Keypad-1/End), 50 (Keypad-2/Down), 51 (Keypad-3/PgDn)

52 (Keypad-0/Ins), 53 (Keypad-./Del)

54 (Alt-SysRq) on a 84+ key keyboard

55 is less common; occurs e.g. as F11 on a Cherry G80-0777 keyboard, as F12 on a Telerate keyboard, as PF1 on a Focus 9000 keyboard, and as FN on an IBM ThinkPad.

56 mostly on non-US keyboards. It is often an unlabelled key to the left or to the right of the left Alt key.

57 (F11), 58 (F12) both on a 101+ key keyboard

59-5a-…-7f are less common. Assignment is essentially random. Scancodes 55-59 occur as F11-F15 on the Cherry G80-0777 keyboard. Scancodes 59-5c occur on the RC930 keyboard. X calls 5d `KEY_Begin’. Scancodes 61-64 occur on a Telerate keyboard. Scancodes 55, 6d, 6f, 73, 74, 77, 78, 79, 7a, 7b, 7c, 7e occur on the Focus 9000 keyboard. Scancodes 65, 67, 69, 6b occur on a Compaq Armada keyboard. Scancodes 66-68, 73 occur on the Cherry G81-3000 keyboard. Scancodes 70, 73, 79, 7b, 7d occur on a Japanese 86/106 keyboard.

Scancodes f1 and f2 occur on Korean keyboards.

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值