【问题标题】:Catching joystick events with PySDL2使用 PySDL2 捕捉操纵杆事件
【发布时间】:2013-10-30 18:42:14
【问题描述】:

我正在使用用于 python 的新的(ish)SDL2 包装器PySDL2,我似乎看不到事件队列中弹出任何操纵杆事件。 Keydown 事件很好,当我明确地轮询操纵杆时,我可以很好地获得轴状态(并观察它随着我移动轴而改变,正如预期的那样)。这是我使用队列的代码:

import sdl2
import sdl2.ext
sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO)
sdl2.SDL_Init(sdl2.SDL_INIT_JOYSTICK)
joystick = sdl2.SDL_JoystickOpen(0)
sdl2.ext.Window("test", size=(800,600),position=(0,0),flags=sdl2.SDL_WINDOW_SHOWN)
window.refresh()) 
while True:
    for event in sdl2.ext.get_events():
        if event.type==sdl2.SDL_KEYDOWN:
            print sdl2.SDL_GetKeyName(event.key.keysym.sym).lower()
        elif event.type==sdl2.SDL_JOYAXISMOTION:
            print [event.jaxis.axis,event.jaxis.value]

这会打印出所有 keydown 事件,但绝不会打印任何轴运动事件。相比之下,这是我显式轮询轴状态的代码:

import sdl2
import sdl2.ext
sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO)
sdl2.SDL_Init(sdl2.SDL_INIT_JOYSTICK)
joystick = sdl2.SDL_JoystickOpen(0)

while True:
    sdl2.SDL_PumpEvents()
    print sdl2.SDL_JoystickGetAxis(joystick,0)

这很好用,但如果状态没有改变,我不想浪费时间轮询状态,所以如果我能让它工作,我更喜欢事件队列方法。有什么建议吗?

如果重要的话,我在 Mac OS 10.9 上运行 python 2.7.5。我试过罗技 USB 游戏手柄和 Xbox 360 有线游戏手柄(通过 tattiebogle.net 驱动程序启用)。上面我讨论了轴事件,因为这是我需要的,但我已经检查过,没有任何操纵杆事件发布到事件队列中。

【问题讨论】:

  • 对不起,我不能复制这个。一方面,使用你拥有的代码,你不会得到任何输出,因为你实际上并没有打开一个窗口。你把这个放在一边了吗?如果你真的打开一个窗口(使用SDL_CreateWindow(...))会发生什么?我已经完全使用了你的代码(除了打开一个窗口)并且一切正常。我得到要打印的轴事件。您使用的是什么类型的操纵杆?您是否尝试过在启用 DEBUG_JOYSTICK 和 DEBUG_INPUT_EVENTS 的情况下构建 SDL?
  • 有趣。该代码确实在没有窗口的情况下打印输出,并且添加窗口(通过window = sdl2.ext.Window("test", size=(800,600),position=(0,0),flags=sdl2.SDL_WINDOW_SHOWN); window.refresh())不会改变上面报告的行为。我没有自己编译 SDL2,而是简单地安装了 mac 框架。我将尝试按照您的建议获取源代码并使用调试进行构建。
  • 其实,虽然我对./configure; make; sudo make install很熟悉,但我不确定如何添加调试标志...
  • 你应该可以在环境变量CFLAGS中定义它们。
  • @MarkHildreth 事实证明,如果我从源代码构建 SDL2 而不是使用预构建的 mac 框架,那么一切正常。愿意发布答案以获得您的帮助吗?

标签: python sdl joystick sdl-2 pysdl2


【解决方案1】:

事实证明,从源代码构建 SDL2(2.0-1;通过 PySDL2-0.7.0 访问)会生成一个构建,游戏杆事件做发布到事件队列(尽管您确实需要创建一个窗口)。似乎问题出在我使用的 SDL2 的 mac 框架版本(来自here)。

【讨论】:

    【解决方案2】:
    import ctypes
    import time
    from sdl2 import *
    
    
    class Joystick:
        def __init__(self):
            SDL_Init(SDL_INIT_JOYSTICK)
            self.axis = {}
            self.button = {}
    
        def update(self):
            event = SDL_Event()
            while SDL_PollEvent(ctypes.byref(event)) != 0:
                if event.type == SDL_JOYDEVICEADDED:
                    self.device = SDL_JoystickOpen(event.jdevice.which)
                elif event.type == SDL_JOYAXISMOTION:
                    self.axis[event.jaxis.axis] = event.jaxis.value
                elif event.type == SDL_JOYBUTTONDOWN:
                    self.button[event.jbutton.button] = True
                elif event.type == SDL_JOYBUTTONUP:
                    self.button[event.jbutton.button] = False
    
    
    if __name__ == "__main__":
        joystick = Joystick()
        while True:
            joystick.update()
            time.sleep(0.1)
            print(joystick.axis)
            print(joystick.button)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多