(三)事件队列与一次发生的操作
1. 事件保存每次动作
按下空格、松开空格、点击鼠标是三次动作,可以在队列中分别观察:
# 项目文件:demos/event_queue.py
# 放入三项已知事件,再按到达次序取出;get 之后队列中的这些事件已被取走。
import pygame
pygame.display.init()
try:
pygame.display.set_mode((1, 1), pygame.HIDDEN)
pygame.event.clear()
pygame.event.post(pygame.event.Event(pygame.KEYDOWN, key=pygame.K_SPACE))
pygame.event.post(pygame.event.Event(pygame.KEYUP, key=pygame.K_SPACE))
pygame.event.post(
pygame.event.Event(pygame.MOUSEBUTTONDOWN, button=1, pos=(120, 80))
)
for event in pygame.event.get():
if event.type in {pygame.KEYDOWN, pygame.KEYUP}:
print(pygame.event.event_name(event.type), pygame.key.name(event.key))
elif event.type == pygame.MOUSEBUTTONDOWN:
print("MouseButtonDown", event.button, event.pos)
print("剩余", len(pygame.event.get()))
finally:
pygame.quit()依次输出 KeyDown space、KeyUp space、MouseButtonDown 1 (120, 80),最后是 剩余 0。示例用 post 放入已知事件;真实窗口中的系统操作也会进入这个队列。get 取走当前队列里的事件,下一次读取不会再拿到已经处理过的这三项。
event.type 指明事件类别;键盘事件带 key,鼠标按下事件带 button 和发生时的 pos。只在相应的事件分支读取这些属性。窗口进入暂停或结束画面后,也要继续处理队列,关闭、恢复和重开操作才能生效。事件队列
2. 事件与持续状态分开使用
开始、暂停、切换声音适合响应一次 KEYDOWN。移动则要知道“这一刻仍然按着哪个方向”,后面用 pygame.key.get_pressed() 每帧读取持续状态。
如果每帧发现 P 仍被按住就切换暂停,按住短短一会儿也会切换很多次。反过来,若只在 KEYDOWN 那一瞬间移动一次,持续按着方向键也不会每帧自动取得新的位移。先区分动作的语义,再选择事件或状态。