读取事件
事件是驱动游戏进行和分支的重要部分,没有事件的存在,游戏只会在原地踏步并且不能响应任何玩家的操作,甚至连退出游戏都十分困难。事件不仅会来自于用户,也可能会来自系统,事件随时可能发生,并且量级巨大。pygame支持用户的各种操作,包括键盘、鼠标还有游戏手柄等,并且使用队列来处理这些巨大量级的事件。
在实际开发中,常常用pygame.event.get()
这个生成器来读取队列中的事件。pygame.event.get()
通常不会阻塞游戏的主循环,而pygame.event.wait()
就不一样了,它会让整个程序停下来等待下一个事件的发生。
事件通常可以使用event.type
属性来判断这个事件的类型,通过区分不同的事件类型,我们可以在程序中做出响应的处理。pygame中常用的事件类型有以下这些。
事件类型 | 产生途径 | 可用成员 |
---|---|---|
QUIT | 用户按下窗口关闭按钮或者执行退出 | 无 |
ACTIVEEVENT | pygame窗口获得焦点或者失去焦点 | gain 、state |
KEYDOWN | 键盘被按下 | unicode 、key 、mod |
KEYUP | 键盘被放开 | key 、mod |
MOUSEMOTION | 鼠标移动 | pos 、rel 、buttons |
MOUSEBUTTONDOWN | 鼠标按键按下 | pos 、button |
MOUSEBUTTONUP | 鼠标按键抬起 | pos 、button |
JOYAXISMOTION | 手柄移动 | joy 、axis 、value |
JOYBALLMOTION | 手柄控制球移动 | joy 、axis 、value |
JOYHATMOTION | 手柄数位杆移动 | joy 、axis 、value |
JOYBUTTONDOWN | 手柄按键按下 | joy 、button |
JOYBUTTONUP | 手柄按键抬起 | joy 、button |
VIDEORESIZE | 窗口缩放 | size 、w 、h |
VIDEOEXPOSE | 窗口显示 | 无 |
USEREVENT | 用户自定义事件 | 无 |
键盘事件
键盘事件比较简单,只是对按下的按键进行记录,不同的成员用来记录不同类型的按键。key
用来记录按下或者释放的键值,由于键值是一个整型数字,并不方便使用,所以pygame在pygame.locals
中提供了一系列的常量来供使用,其中按键采用K_xxx
来表示,例如K_a
表示按下了字母A键,空格和回车分别是K_SPACE
和K_RETURN
。
mod
用来记录组合键信息,组合键通常使用位运算来判断,例如event.mod & pygame.locals.KMOD_CTRL
如果为真,则表示用户按下了Ctrl键。常用的其他按键还有KMOD_SHIFT
和KMOD_ALT
。
在pygame.key
模块中,还提供了一个.get_pressed()
函数,可以获得当前所有已经按下的键盘的值。这个函数会返回一个元组,元素的索引是键值,值为是否按下。所以对已经按下的键的判断还可以使用以下方式来完成。
pressed_keys = pygame.key.get_pressed()
if pressed_keys[K_SPACE]:
# 处理空格键按下的逻辑
pass
同样,获取组合键信息的函数是.get_mods()
。
处理鼠标事件
MOUSEMOTION
事件在鼠标动作时产生,会在产生的事件中提供三个成员,其中buttons
成员是一个元组,其中有三个整型值,分别代表左、中、右三个键,哪个值为1,就代表对应的哪个键被按下了。pos
成员表示目前鼠标的位置。rel
成员表示当前事件与上次事件发生时的鼠标位置距离。
MOUSEBUTTONDOWN
和MOUSEBUTTONUP
两个事件只在鼠标按键点击和释放的时候产生,其中button
成员代表哪个按键被操作,pos
依旧代表发生事件时的鼠标位置。
阻止事件和自定义事件
通常不是所有的事件都是程序感兴趣的,但是pygame将其排入了队列,即便是不予理睬也会稍微的影响性能。这时可以使用pygame.event.set_blocked([事件类型名称])
来对事件进行过滤,所有列在列表中的事件类型,pygame都会不再捕获。相反,使用pygame.event.set_allowed()
可以用来设置允许的事件。
Pygame也支持自定义事件,为了使用自定义事件,需要先创建一个事件,再将其发送到pygame的事件队列中。这里的自定义事件并不仅是前表中的USEREVENT,也可以是自定义事件类型,或者是按键、鼠标等事件类型。例如可以使用以下示例来发送键盘事件和自定义事件。
# 创建键盘事件
key_event = pygame.event.Event(KEYDOWN, key=K_SPACE, mod=0, unicode=u' ')
pygame.event.post(key_event)
# 使用字典创建键盘事件
key_event = pygame.event.Event(KEYDOWN, {'key': K_SPACE, 'mod': 0, 'unicode': u' '})
# 创建自定义事件
ANEWUSEREVENT = USEREVENT + 1
custom_event = pygame.event.Event(ANEWUSEREVENT, message='Hello from custom event')
pygame.event.post(custom_event)