2

我编写了一个简单的 python 脚本,可以控制操纵杆的光标。此处记录了我了解其工作原理的方法。现在它完美无缺,但是一旦我启动脚本以使用操纵杆,鼠标就没有用了,因为每当有新的操纵杆事件出现时,我的 python 例程都会将值设置回其原始值。

因此,只要按下键盘的一个键,我就希望我的操纵杆事件被忽略。我遇到了该pygame.key.get_pressed()方法,但这似乎仅在 pygame 窗口处于焦点时才有效。我希望这个脚本在后台运行。我应该开始使用非 pygame 事件来收听键盘,还是有办法通过 pygame 跟踪类似于在后台识别的操纵杆事件的键盘事件?

4

2 回答 2

4

我希望 pygame 设置自己的“沙箱”,这样就很难检测到来自其窗口外的输入。您之前的问题表明您也在使用该win32api模块。我们可以使用它来检测全局按键。

在全局范围内检测按键的正确方法是使用SetWindowsHookEx设置键盘挂钩。不幸的是,win32api 没有公开该方法,因此我们将不得不使用效率较低的方法。

GetKeyState方法可用于确定键是按下还是按下。您可以不断检查某个键的状态,以查看用户最近是否按下或释放了它。

import win32api
import time

def keyWasUnPressed():
    print "enabling joystick..."
    #enable joystick here

def keyWasPressed():
    print "disabling joystick..."
    #disable joystick here

def isKeyPressed(key):
    #"if the high-order bit is 1, the key is down; otherwise, it is up."
    return (win32api.GetKeyState(key) & (1 << 7)) != 0


key = ord('A')

wasKeyPressedTheLastTimeWeChecked = False
while True:
    keyIsPressed = isKeyPressed(key)
    if keyIsPressed and not wasKeyPressedTheLastTimeWeChecked:
        keyWasPressed()
    if not keyIsPressed and wasKeyPressedTheLastTimeWeChecked:
        keyWasUnPressed()
    wasKeyPressedTheLastTimeWeChecked = keyIsPressed
    time.sleep(0.01)

警告:与任何“while True sleep and then check”循环一样,此方法可能比等效的“设置回调并等待”方法使用更多的 CPU 周期。您可以延长sleep期间的长度来改善这一点,但关键检测将需要更长的时间。例如,如果您睡了整整一秒钟,那么在您按下一个键和操纵杆被禁用之间可能需要一秒钟的时间。

于 2012-11-14T15:37:54.783 回答
0

当您的窗口获得或失去焦点时,您会得到一个ACTIVEEVENT. 它gainstate属性告诉你你获得或失去了哪个状态。最简单的解决方案可能是在您的主事件循环中捕获这些事件并使用它们来跟踪您是否关注的天气。然后,如果您没有焦点,则可以忽略操纵杆事件。

于 2012-11-14T15:41:26.740 回答