Pygame检测DragonRise摇杆事件时空事件分支误触发问题求助
问题根因
- Pygame的
pygame.JOYAXISMOTION事件仅在摇杆轴向数值发生变化时触发。当你推动摇杆保持在固定位置时,轴数值不再变化,不会产生新的摇杆事件,pygame.event.get()返回空列表,就会进入else分支,这是你遇到现象的核心原因。 - 原代码存在逻辑冗余:遍历摇杆事件时直接读取摇杆全局轴状态,没有用到事件本身的属性,即使触发其他轴的运动事件,也会重复读取轴1的状态做判断。
修复方案
根据你的实际需求可选两种实现:
方案1:只要摇杆有有效输入就执行控制逻辑(符合你当前操作预期)
不需要依赖事件是否存在,每次循环先判断摇杆当前状态,有有效输入就执行控制逻辑,无输入再判断是否有其他事件处理,最后走其他业务逻辑:
import pygame done = False deadzone = 0.1 pygame.init() pygame.joystick.init() joystick = pygame.joystick.Joystick(0) joystick.init() clock = pygame.time.Clock() # 用pygame内置时钟控制循环精度 while not done: # 先清空事件队列,避免事件堆积导致程序无响应 events = pygame.event.get() # 先处理退出类通用事件 for event in events: if event.type == pygame.QUIT: done = True # 判断摇杆轴1的当前状态,不在死区就执行控制逻辑 axis1_val = joystick.get_axis(1) if axis1_val < -1 * deadzone: print('Throttle Up') elif axis1_val > deadzone: print('Throttle Down') else: # 摇杆在死区,执行其他业务逻辑 print('No Valid Input, Run Other Logic') # 控制循环间隔为70ms,精度比time.sleep更高 clock.tick(1000//70)
方案2:仅当有新摇杆事件时才更新控制逻辑(贴合原始设计思路)
如果确实需要仅在轴状态变化时才执行控制逻辑,其余时间走其他业务,可以增加状态变量缓存上一次的轴值,需要时可直接复用缓存值保持控制输出:
import pygame done = False deadzone = 0.1 last_axis1_val = 0 # 缓存上一次轴1的数值 pygame.init() pygame.joystick.init() joystick = pygame.joystick.Joystick(0) joystick.init() clock = pygame.time.Clock() while not done: has_joystick_event = False events = pygame.event.get() for event in events: if event.type == pygame.QUIT: done = True if event.type == pygame.JOYAXISMOTION and event.axis == 1: has_joystick_event = True if event.value < -1 * deadzone: print('Throttle Up') elif event.value > deadzone: print('Throttle Down') last_axis1_val = event.value if not has_joystick_event: # 无新摇杆事件时执行其他业务逻辑 # 如需保持摇杆不动时的控制输出,可直接读取last_axis1_val处理 print('No New Joystick Event') clock.tick(1000//70)
优化建议
- 不要用
time.sleep控制循环间隔,pygame.time.Clock的tick方法会自动处理事件队列调度,计时精度更高,也能避免程序被系统判定为无响应。 - 处理摇杆事件时优先用事件自带的
axis、value属性,不需要重复调用joystick.get_axis,性能更好也更准确。 - 必须处理
pygame.QUIT等系统事件,否则事件队列堆积会导致程序卡顿崩溃。
内容的提问来源于stack exchange,提问作者wvthoog
相关产品推荐
相关产品推荐

