Python 现代开发学习笔记

(三)事件队列与一次发生的操作

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 那一瞬间移动一次,持续按着方向键也不会每帧自动取得新的位移。先区分动作的语义,再选择事件或状态。

笔记正文与全部题解 · Ctrl / ⌘ K