我一直在做一个项目,把操纵杆(在我的例子中是Logitech极限3D)映射到鼠标和键盘上,这样我就可以在不支持游戏的网络游戏中使用它了。我的设计目标是:
这是我的代码:
import pygame
from pygame.locals import *
import ctypes
import math
def main():
print('Python Slither controller is ready.')
pygame.init()
clock = pygame.time.Clock()
joysticks = []
for i in range(0, pygame.joystick.get_count()):
joysticks.append(pygame.joystick.Joystick(i))
joysticks[-1].init()
while 1:
clock.tick(60)
updateData(pygame.joystick.Joystick(0))
doActions()
for event in pygame.event.get():
if event.type == QUIT:
print ("Received event 'Quit', exiting.")
return
controls = {'trigger': 0,
'x-axis': 0,
'y-axis': 0,
'z-axis': 0,
'hat-x': 0,
'hat-y': 0,
'slider': 0,
'button-2': 0,
'button-3': 0,
'button-4': 0,
'button-5': 0,
'button-6': 0,
'button-7': 0,
'button-8': 0,
'button-9': 0,
'button-10': 0,
'button-11': 0,
'button-12': 0}
old_controls = controls.copy()
def updateData(joystick):
global old_controls
old_controls = controls.copy()
controls['trigger'] = joystick.get_button(0)
for i in range(1, 12):
controls['button-'+str(i+1)] = joystick.get_button(i)
controls['slider'] = joystick.get_axis(2)
controls['x-axis'] = joystick.get_axis(0)
controls['y-axis'] = joystick.get_axis(1)
controls['z-axis'] = joystick.get_axis(3)
controls['hat-x'] = joystick.get_hat(0)[0]
controls['hat-y'] = joystick.get_hat(0)[1]
######################################################
######################################################
######################################################
def keyAction(keyChar):
return (lambda old, new:
keyEvent(bool(new), keyChar))
def mouseMoveAction():
pass
def mouseScrollAction(scale):
return (lambda old, new:
mouseScroll(int((old-new)*scale)))
def mousePressAction():
return (lambda old, new:
mouseEvent(new))
mousePos = [0,0]
def mouseMoveAction(rangeOfMotion, axis, minDist):
def ret(old, new):
if dist(mousePos[0], mousePos[1],
centerOfDisplay[0], centerOfDisplay[1]) > minDist:
mousePos[axis] = int(rangeOfMotion * new)
mouseMoveAroundCenter(mousePos[0], mousePos[1])
return ret
actions = {
'trigger': mousePressAction(),
'x-axis': mouseMoveAction(150, 0, 50),
'y-axis': mouseMoveAction(150, 1, 50),
'z-axis': lambda old, new: 0,
'hat-x': lambda old, new: 0,
'hat-y': lambda old, new: 0,
'slider': mouseScrollAction(100),
'button-2': lambda old, new: 0,
'button-3': keyAction('.'),
'button-4': lambda old, new: 0,
'button-5': keyAction('f'),
'button-6': lambda old, new: 0,
'button-7': keyAction('w'),
'button-8': keyAction('q'),
'button-9': lambda old, new: 0,
'button-10': keyAction('tab'),
'button-11': lambda old, new: 0,
'button-12': keyAction('esc')
}
def doActions():
for key in controls:
if old_controls[key] != controls[key]:
actions[key](old_controls[key], controls[key])
######################################################
######################################################
######################################################
# https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
keys = {'f': 0x46,
'esc': 0x1B,
'q': 0x51,
'.': 0xBE,
'tab': 0x09,
'w': 0x57}
def keyEvent(keyDown, keyName):
eventConstants = {'key_down': 0, 'key_up': 0x0002}
ctypes.windll.user32.keybd_event(keys[keyName], 0, eventConstants['key_down' if keyDown else 'key_up'], 0)
# https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
# only the required consts are shown, more can be found at the link
mouseEventConstants = {'absolute_pos': 0x8000,
'left_down': 0x0002,
'left_up': 0x0004,
'wheel': 0x0800}
# https://msdn.microsoft.com/en-us/library/ms724385(v=vs.85).aspx
centerOfDisplay = ( int(ctypes.windll.user32.GetSystemMetrics(0) / 2),
int(ctypes.windll.user32.GetSystemMetrics(1) / 2))
def mouseMoveAroundCenter(x, y):
ctypes.windll.user32.SetCursorPos(x + centerOfDisplay[0],
y + centerOfDisplay[1])
def mouseScroll(ticks):
# https://msdn.microsoft.com/en-us/library/ms646260(v=vs.85).aspx
amtPerTick = 120
ctypes.windll.user32.mouse_event(
mouseEventConstants['wheel'],
0, 0, ticks * amtPerTick, 0)
def mouseEvent(pressed):
ctypes.windll.user32.mouse_event(
mouseEventConstants['left_down' if pressed else 'left_up'],
0, 0, 0, 0)
def dist(x1, y1, x2, y2):
return math.sqrt( (x1-x2)**2 + (y1-y2)**2 )
if __name__ == "__main__":
main()(如果你想运行它,你就需要玩游戏。这个程序是用python3.x编写的,但是它也可以在python2.x上工作。)
任何反馈都是有帮助的!谢谢!
发布于 2023-01-03 01:29:08
我非常喜欢主循环中的这个:
updateData(pygame.joystick.Joystick(0))
doActions()简明扼要。
您可以通过执行Extract生成def look_for_quit_event():来继续该主题
干的。controls分配有点冗长,可能会在代码中更深入地进行。更喜欢:
controls = { key: 0
for key in actions }keys分配不必要地不透明:
keys = {'f': 0x46,
'esc': 0x1B,
'q': 0x51,
'.': 0xBE,
'tab': 0x09,
'w': 0x57}请给我这个。
keys = {ch: ord(ch) for ch in "fqw."}
keys["tab"] = 9
keys["esc"] = 0x1B感谢您提供的各种MSDN URL,它们非常有用。
https://codereview.stackexchange.com/questions/151975
复制相似问题