代码已放到码云
https://gitee.com/photographer_adam/Based-on-image-processing-and-tensorflow-to-realize-GTA5-vehicle-automatic-driving
一开始想采用PyAutoGUI
,然后GTA并不支持,遂采用DirectX的输入模式
这部分的代码看不太懂了,我就Github上搜了一下代码,然后调整了一下。
Keys.py文件
键盘映射,主要是把键位映射为DirectX能读的形式(16进制的一串字符),定义如下
class Key_Mapping:
num1 = 0x02
num2 = 0x03
num3 = 0x04
num4 = 0x05
num5 = 0x06
num6 = 0x07
num7 = 0x08
num8 = 0x09
num9 = 0x0a
num0 = 0x0b
escape = 0x01
equal = 0x0d
backspace = 0x0e
tab = 0x0f
q = 0x10
w = 0x11
e = 0x12
r = 0x13
t = 0x14
y = 0x15
u = 0x16
i = 0x17
o = 0x18
p = 0x19
enter = 0x1c
lcontrol = 0x1d
a = 0x1e
s = 0x1f
d = 0x20
f = 0x21
g = 0x22
h = 0x23
j = 0x24
k = 0x25
l = 0x26
z = 0x2c
x = 0x2d
c = 0x2e
v = 0x2f
b = 0x30
n = 0x31
m = 0x32
shift = 0x36
multiply = 0x37
space = 0x39
capital = 0x3a
f1 = 0x3b
f2 = 0x3c
f3 = 0x3d
f4 = 0x3e
f5 = 0x3f
f6 = 0x40
f7 = 0x41
f8 = 0x42
f9 = 0x43
f10 = 0x44
numlock = 0x45
f11 = 0x57
f12 = 0x58
divide = 0xb5
home = 0xc7
up = 0xc8
prior = 0xc9
left = 0xcb
right = 0xcd
end = 0xcf
down = 0xd0
next = 0xd1
insert = 0xd2
delete = 0xd3
divide = 0xb5
home = 0xc7
up = 0xc8
prior = 0xc9
left = 0xcb
right = 0xcd
end = 0xcf
down = 0xd0
next = 0xd1
insert = 0xd2
delete = 0xd3
模拟键盘的点击,松开等动作
注:主要是用PressKey(), ReleaseKey()
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))
调用Keys.py文件
注:
- 主要引用Keys.py文件的PressKey, ReleaseKey, Key_Mapping
- 先倒计时一下,需要在结束前把鼠标移动到游戏窗口,点击一下
- PressKey()要和ReleaseKey()配合使用,详见代码
from Keys import PressKey, ReleaseKey, Key_Mapping
import time
i = 3
while i != 0:
print("time:", i)
time.sleep(0.5)
i -= 1
PressKey(Key_Mapping.w)
print("start forward")
time.sleep(3)
ReleaseKey(Key_Mapping.w)
print("end forward")
print("start back")
PressKey(Key_Mapping.s)