处理 pygame 中的各类事件

614 阅读11分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第19天,点击查看活动详情

Pygame 了解事件

在《你好世界》中,我们只处理了QUIT事件,这是必不可少的,除非你想拥有不朽的Pygame窗口!Pygame会创建其他事件来通知您鼠标移动和按键等内容。

事件可以随时生成,无论您的程序当前在做什么。例如,当用户按下游戏手柄上的启动按钮时,您的代码可能会在屏幕上绘制一个坦克。由于您无法在事件发生的那一刻做出反应,因此Pygame将它们存储在队列中,直到您准备好处理它们(通常在主游戏循环的开头)。您可以将事件队列视为一排等待进入建筑物的人员,每个人员都包含有关事件的特定信息。当玩家按下开火按钮时,操纵杆事件到达,并包含有关按下哪个键的信息。同样,当玩家释放触发按钮时,同一操纵杆事件的克隆将到达,其中包含有关已释放按钮的信息。它们可以跟随鼠标事件和键事件。

检索事件

在前面的示例中,我们称之为“派弈事件”。get () 检索所有事件并将其从队列中删除,这就像打开门让每个人都进来一样。这可能是处理事件的最佳方式,因为它可以确保我们在继续在屏幕上绘制内容之前已经处理了所有内容 - 但是还有其他方法可以使用事件队列。如果你叫皮游戏。事件。等(),Pygame会等到一个事件发生后再回来,这就像在门口等着,直到有人来。这

函数不常用于游戏,因为它会挂起脚本,直到发生某些事情,但它对于与系统上的其他程序(如媒体播放器)协作较多的Pygame应用程序非常有用。另一种选择是 皮博弈 。event.pol1(),如果存在一个正在等待的事件,则返回单个事件,如果队列中没有事件,则返回 NOEVENT 类型的虚拟事件。无论使用哪种方法,都不允许它们堆积,因为事件队列的大小有限,如果队列溢出,事件将丢失。

有必要定期调用至少一个事件处理函数,以便Pygame可以在内部处理事件。如果不使用任何事件处理函数,可以调用 pygame 。事件。泵 () 代替事件环路。

事件对象包含一些描述所发生事件的成员变量。它们包含的信息因事件而异。所有事件对象唯一共同的是 type,它是指示事件类型的值。您首先查询的正是此值,以便您可以决定如何处理它。表 3-4 列出了您可能收到的标准事件;我们将在本章中介绍其中的一些。

图片.png

图片.png

让我们编写一个简单的 Pygame 脚本来显示生成的所有事件。清单 3-2 使用 pygame.event.wait () 来等待单个事件。一旦它得到一个,它就会把它变成一个带有str的字符串,并将其添加到列表中。代码的其余部分显示新事件以及屏幕上可以容纳的尽可能多的先前事件。它使用字体模块来显示文本(我们将在后面讨论)。

提示 如果将清单 3-2 中的填充颜色更改为 (0,0,0) 并将字体颜色更改为 (0, 255, 0),它看起来将有点像 Matrix 样式的代码。你可能需要稍微发挥你的想象力!

图片.png

图片.png

如果运行清单 3-2,您将看到一个简单的黑色窗口。如果将鼠标移到窗口上,您将开始看到输出到控制台的输出(请参阅图 3-2)。这些事件指定鼠标的当前位置、自上次运动事件以来鼠标移动的距离以及当前按下的按钮。您可以使用pygame.mouse模块获取鼠标的当前位置,就像我们在“你好世界”示例中所做的那样,但是您可能会丢失有关玩家一直在做什么的信息。这在台式计算机上是一个特殊问题,台式计算机在后台执行大量工作,并且可能偶尔会暂停游戏一小段时间。对于鼠标光标,您只需要知道鼠标在每个帧的开头的位置,因此使用pygame.mouse.get_pos()是合理的。如果您使用鼠标移动来驱动坦克并启动按钮,则最好使用事件,以便游戏可以更密切地监视玩家一直在做什么。

图片.png

处理鼠标运动事件

如您所见,每当您将鼠标移动到 Pygame 窗口上时,就会发出鼠标运动事件。它们包含以下三个值:

按钮 - 由三个数字组成的元组,对应于鼠标上的按钮。

所以按钮[0]是鼠标左键,按钮[1]是中间按钮(如鼠标滚轮),按钮[2]是右键

按钮。如果按下按钮,则其值设置为1;如果未按下,则该值将为 0。可以一次按下多个按钮。

·pos-一个包含生成事件时鼠标位置的元组。

·rel-一个元组,其中包含自

最后一次鼠标运动事件(有时称为鼠标咪咪)。

处理鼠标按钮事件

除了运动事件之外,鼠标还会生成鼠标按钮下和鼠标按钮事件。如果在消息队列脚本上单击鼠标,您将首先看到 down 事件,然后在将手指从按钮上移开时看到 up 事件。那么,为什么会有这两个事件呢?如果您使用鼠标按钮作为触发器来触发

火箭,你只需要其中一个事件,但你可能有一个不同类型的武器,比如一把链枪,在按住按钮时连续射击。在这种情况下,您将在下降事件中启动链枪加速,并使其开火,直到您获得相应的上升事件。这两种类型的鼠标按钮事件都包含以下两个值:

按钮 - 按下的按钮的编号。值为 1 表示按下了鼠标左键,2 表示按下了中间按钮,3 表示按下了右键。

·pos-一个包含生成事件时鼠标位置的元组。

处理键盘事件

键盘和操纵杆具有类似的上下事件;按键时发出按键,释放键时发出按键。清单 3-3 演示了如何使用光标键响应 KEYUP 和 KEYDOWN 事件以在屏幕上移动某些内容。如果运行此列表,您将看到一个包含简单背景图像的窗口。向上、向下、向左或向右按,背景将沿该方向滑动。将手指从光标键上移开,背景将停止移动。

图片.png

图片.png

清单 3-3 的开头就像“你好世界”一样;它导入并初始化Pygame,然后加载背景图像。此脚本中的事件循环是不同的,因为它处理

键控和键控。这些关键事件都包含相同的三个值:

key - 这是一个表示按下或释放的键的数字。键盘上的每个物理键都有一个以K_开头的常量。字母键通过K_z K_a,但也有所有其他键(如 K_SPACE 和 K RETURN)的常量。有关您可以使用的关键常量的完整列表,请参见

www.pygame.org/docs/ref/ke…

mod - 此值表示与其他键(如移位、Alt 和 Ctrl)组合使用的键。这些修饰键中的每一个都由一个以KMOD_开头的常量表示,例如 KMOD SHIFT、KMOD ALT 和 KMOD CTRL。使用按位 AND 运算符检查这些值。例如,如果按 Ctrl 键,则模组 CTRL 的计算结果将为 True。

www.pygame.org/docs/ref/ke… 提供了修饰键的完整列表。

unicode - 这是所按下的键的 Unicode 值。它是通过将按下的键与任何按下的修饰键组合在一起而产生的。英语字母表和其他语言中的每个符号都有一个 Unicode 值。您不会经常在游戏中使用此值,因为按键的使用往往更像开关,而不是用于输入文本。一个例外是输入高分表,您希望玩家能够键入非英语字母以及混合大写和小写。

在 KEYDOWN 的处理程序中,我们检查与光标键对应的四个键常量。如果按 K _LEFT,则move_x的值设置为 -1;如果按 K RIGHT,则将其设置为 +1。此值稍后将添加到背景的 x 坐标中,以便向左或向右移动。还有一个move_y值,如果按下K_UP或K_DOWN,则会设置该值,该值将垂直移动背景。

我们还处理 KEYUP 事件,因为我们希望在用户释放光标键时后台停止移动。KEYUP 事件的处理程序中的代码类似于 down 事件,但它move_x或move_y设置回零以阻止背景移动。

在事件循环之后,我们所要做的就是将值move_x和move_y添加到x和y,然后在(x,y)处绘制背景。您以前唯一没有见过的是 screen.fill((0, 0, 0) ),它用于将显示屏清除为黑色(颜色在第 4 章中进行了说明)。这条线是必要的,因为如果我们移动背景图像,它不再覆盖整个显示器 - 我想这在技术上意味着它不再是背景!

筛选事件

并非所有事件都需要在每个游戏中处理,并且通常有其他方法可以获取事件可能为您提供的信息。例如,如果您正在使用

get_pos () 您不需要响应鼠标移动事件。

有时,您还需要暂停对某些事件的处理。如果要在关卡之间播放过场动画,则可能需要忽略输入事件,直到完成。Pygame事件模块具有许多功能来帮助您做到这一点。

您可以使用set_block功能阻止事件队列中的事件。例如,以下行将禁用鼠标移动:

pygame.event.set_blocked(鼠标移动)

如果传入事件类型列表,则将阻止所有这些事件。例如,以下行将通过阻止 KEYDOWN 和 KEYUP 事件来禁用所有键盘输入:

pygame.event.set_blocked([按键,键合])

如果要取消阻止所有事件,请将 None 的值传递到set_blocked。此行将允许在事件队列中发生所有事件:

pygame.event.set_blocked(无)

set_blocked的反面是set_allowed,它选择应允许(取消阻止)的事件。它还采用单个事件类型或事件类型列表。但是,如果传入 None 的值,它将有效地阻止所有事件。您可以询问Pygame事件当前是否被pygame阻止。event.get_block,它采用单个事件类型。

发布事件

通常,Pygame会为您创建所有事件,但您可以创建自己的事件。您可以使用此功能来播放演示(通过复制玩家的输入),或模拟猫在键盘上行走的效果(我喜欢让我的游戏证明猫)。

要发送事件,您首先使用 pygame.event.事件构造一个事件对象,然后使用 pygame 发布它。事件。发布。事件将放置在队列的末尾,准备在事件循环中检索。下面介绍如何模拟玩家按下空格键:

图片.png

Event 构造函数采用事件的类型(如表 3-4 中的事件之一),后跟事件应包含的值。由于我们正在模拟 KEYDOWN 事件,因此我们需要提供事件处理程序期望存在的所有值。如果您愿意,可以将这些值作为字典提供。此行创建相同的事件对象:

图片.png

除了模拟Pygame生成的事件外,您还可以创建全新的事件。您所要做的就是为事件使用一个高于 USEREVENT 的值,这是 Pygame 将用于其自己的事件 ID 的最大值。如果您想在继续绘制到屏幕之前在事件循环中执行某些操作,这有时很有用。下面是响应猫咪在键盘上行走的用户事件示例:

图片.png

处理用户事件的方式与Pygame的通常事件相同

生成 - 只需检查事件类型以查看它是否与您的自定义事件匹配。以下是处理卡顿键盘事件的方法:

图片.png