pygame 接受用户输入(键盘控制)

747 阅读14分钟

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

接受用户输入

玩家可以通过多种方式与游戏进行交互,本章详细介绍了各种输入设备。除了从设备中检索信息外,我们还将探讨如何将玩家的行为转换为游戏中有意义的事件。这对任何游戏都非常重要 - 无论游戏的外观和声音有多好,它也必须易于交互。

控制游戏

在典型的家用计算机上,我们几乎可以依靠键盘和鼠标。这种古老的设置是第一人称射击游戏迷的首选,他们喜欢用鼠标控制头部移动(即四处走动),并将一只手放在键盘上进行方向控制和射击。键盘可用于运动,方法是为四个基本方向分配一个键:向上、向下、向左和向右。通过组合按这些键(向上 + 向右、向下 + 向右、向下 + 向左、向上 + 向左)可以指示另外四个方向。但是对于大多数游戏来说,拥有八个方向仍然非常有限,因此它们并不适合需要一点技巧才能玩的游戏。

大多数玩家更喜欢鼠标等模拟设备。标准鼠标是方向控制的理想选择,因为它可以准确地检测到从微小的调整到任何方向的快速扫描。如果您曾经玩过仅具有键盘控制的第一人称射击游戏,那么您会欣赏其中的差异。按下“向左旋转”键会使玩家以恒定的速度像机器人一样旋转,这远不如能够快速转身射击从侧面接近的怪物有用。

键盘和鼠标在游戏中运行良好,这可能有点讽刺意味,因为这两个设备在设计时都没有考虑到游戏。然而,操纵杆和游戏手柄纯粹是为游戏而设计的,并且随着它们用于玩的游戏而发展。第一个操纵杆是仿照飞机上使用的控制装置建模的,并且具有带有单个按钮的简单方向杆。它们在当时的游戏机中很受欢迎,但玩家发现不得不用一只手握住操纵杆底座,同时用另一只手移动操纵杆,这让人感到不舒服。这导致了游戏手柄的发展,它可以用双手握住,但仍然使玩家能够用手指和拇指轻松访问控件。第一个游戏手柄的一侧有方向控制,另一侧有触发按钮。如今,游戏手柄上有许多按钮,到处都是备用手指可以按下它们,还有几根棍子。经典的方向键仍然可以在游戏手柄上找到,但大多数还具有可以检测微调的模拟摇杆。许多还具有力反馈功能,可以通过使游戏手柄摇晃或隆隆声来响应屏幕上的事件,从而为游戏增加额外的维度。毫无疑问,将来游戏手柄将添加其他功能,以进一步增强游戏体验。

还有其他设备可用于游戏,但其中大多数都模仿标准输入设备。因此,如果您的游戏可以使用鼠标播放,那么它也可以使用这些类似鼠标的设备进行游戏。游戏输入设备不断被

改进;考虑虚拟现实的当前状态,例如Oculus Rift,它模拟了您在游戏中以“自由视图”操作鼠标时所期望的一些内容。然而,这里的不同之处在于,你现在有类似鼠标的设备,键盘,然后是Oculus Rift,以便为游戏提供更多的输入。我想你相信输入和处理输入很重要,让我们谈谈键盘!

了解键盘控制

今天使用的大多数键盘都是QWERTY键盘,之所以这样称呼,是因为第一个字母行上的前六个字母拼写出QWERTY。品牌之间有差异;键的形状和大小可能略有不同,但它们在键盘上的位置大致相同。这是一件好事,因为计算机用户不希望每次购买新键盘时都必须重新学习如何打字!我使用过的所有键盘都有五行用于标准键入键:一行用于功能键F1-F12,四行用于在屏幕上移动插入记号。它们还有一个“数字小键盘”,这是一个用于输入数字和求和的键块,以及其他一些杂项键。为了节省空间,笔记本电脑键盘上经常省略数字键盘,因为数字键在键盘的主要部分上是重复的。我们可以使用pygame.key模块检测所有这些键。

注意 虽然它是最常见的,但QWERTY并不是唯一的键盘布局;还有其他键盘,如阿塞拜疆和德沃夏克。可以使用相同的键盘常量,但按键可能位于键盘上的不同位置。如果您允许玩家选择自己的键以在游戏中使用,则他们可以选择最适合其键盘的控件。

检测按键

在Pygame中有两种方法可以检测按键。一种方法是处理 KEYDOWN 事件(在按下某个键时发出)和 KEYUP 事件(在释放键时发出)。这对于键入文本非常有用,因为即使自上一帧以来一段时间内按下并释放了某个键,我们也将始终收到键盘事件。事件还将捕获非常快速的按键以用于触发按钮。但是,当我们使用键盘输入进行移动时,我们只需要在绘制下一帧之前知道键是否按下。在这种情况下,我们可以使用py游戏。按键模块更直接。

键盘上的每个键都有一个与之关联的键常量,这是我们可以用来识别代码中的键的值。每个常量都以K_开头。有字母(K_a到K_z),数字(K_0到K_9)和许多其他常量,如K_f1,K_LEFT和K_RETURN。有关完整列表,请参阅 Pygame 文档

www.pygame.org/docs/ref/ke… K_z,您可能希望有等效的大写版本 -但没有。这样做的原因是大写字母是组合键(Shift + 键)的结果。如果需要检测大写字母或其他 Shift 键,请在包含此类组合键结果的键事件中使用 Un i code 参数。

我们可以使用皮游戏。key.get_pressed功能,用于检测是否按下了某个键。它返回一个布尔值(True 或 False 值)列表,每个关键常量对应一个布尔值。要查找特定键,请使用其常量作为按下列表的索引。例如,如果我们将空格键用作触发按钮,则可以像这样编写触发器代码:

image.png

应该讨论的是,各种键盘对于它们支持多少个并发按键有各种规则。如果你看看游戏键盘,你会发现他们几乎总是列出,作为卖点,他们同时按键多少

支持。许多便宜的键盘支持3-5次同时按键,而游戏键盘可以支持二十年代中期或更多。

在许多游戏中,你可能有一把钥匙可以蹲下,向前移动,稍微扫射一下,然后慢慢移动。也许当你在做这个对角线蹲伏慢速扫射时,你想通过按数字5切换到你的手榴弹。您可能会发现,当您按 5 时,没有任何反应!恐怖!要是你买了专业玩家X“超过9000”键盘!您不仅应该考虑您的玩家可能没有最好的键盘这一事实,请记住,他们总共只有十个手指,但通常只有五个真正使用,因为一只手可能在鼠标上。但是,有很多游戏玩家确实使用用一根手指按下两个或多个键。

另外,您可能需要考虑那些使用游戏垫的人,其中按钮的数量可能会受到严重限制。

考虑到所有这些,让我们编写一个脚本来试验键盘。清单 6- 1 使用get_pressed功能来检测任何按下的键,并在屏幕上显示它们的列表。

image.png

image.png

在清单 6-1 将按下的键作为布尔值列表获取后,它进入一个循环访问每个值的 for 循环。您会注意到,循环通过调用枚举间接循环访问按下的键,枚举是一个内置函数,它返回索引的元组(第一个值为 0,第二个值为 1,依此类推)和迭代列表中的值。如果迭代值(按下)为 True,则表示已按下该键,我们输入一个小代码块以在屏幕上显示它。此代码块使用键盘模块中的另一个函数 pygame。.key。name,它采用一个键常量并返回一个字符串,其中包含键的描述(即,它将K_SPACE转换为“空格”)。

在这里,您可以测试键盘 - 它支持多少个键?您可能会发现在某些情况下,您可以支持多达8个或更多,但其他时候只有4个,或者

类似的东西。这是由于键盘的工作原理(请参阅:www.sjbaker.org/wiki/index.…

标题 = Keyboards_Are_Evil了解更多信息)。我有一个 2005 年的键盘,它仅支持清单 6-1 中的四个键,但我的主键盘是游戏键盘,我注册尽可能多的键没有问题。然而,我没有试图用我的脚。

您可能会注意到,当您运行清单 6-1 时,即使您当时没有触摸它,它也显示按下了 numlock。这是因为 numlock 是一种在键盘中切换状态的特殊键。当它打开时,数字小键盘可用于输入数字。但是,当它关闭时,数字小键盘将用于执行滚动和导航文本的其他键。另一个像这样工作的钥匙是大写锁定键。如果点击大写锁定,清单 6-1 将显示按下的大写锁定,即使它已经释放。

再次点击它以禁用大写锁定状态。另一个这样做的关键是滚动锁(在PC键盘上),现在很少使用。这三个键不应用作触发器,因为 Pygame 无法更改此行为。

让我们来看看这个游戏。关键模块更详细地介绍:

key.get_focused-A Pygame 窗口仅在窗口聚焦时接收关键事件,通常是通过单击窗口标题栏。所有顶级窗口都是如此。如果窗口具有焦点并且可以接收关键事件,则get_focused函数返回 True;否则,它将返回错误。当Pygame在全屏模式下运行时,它将始终具有焦点,因为它不必与其他应用程序共享屏幕。

key.get_pressed - 返回每个键的布尔值列表。如果任何值设置为 True,则按下该索引的键。key.get_mods - 返回一个值,该值指示按下了哪些修饰键。修饰键是与其他键组合使用的键,如 Shift、Alt 和 Ctrl。若要检查是否按下了修饰键,请将按位 AND 运算符 (&) 与KMOD_constants之一一起使用。例如,要检查是否按下了左 Shift 键,您可以使用

皮.key·get_mods () & KMOD_LSHIFT.

皮游戏。.key。set_mods - 您还可以设置其中一个修饰键来模拟按下键的效果。若要设置一个或多个修饰键,请将KMOD_constants与按位 OR 运算符 (I) 组合在一起。例如,要设置 Shift 键和 Alt 键,可以使用 pygame.key.set_mods (KMOD_SHIFT |KMOD_ALT)。

皮游戏。.key。set_repeat - 如果您打开自己喜欢的文本编辑器并按住字母键,您将看到在短暂的延迟后键开始重复,如果要输入字符,这将非常有用

多次没有按下和释放多次。您可以要求Pygame向您发送重复KEY_DOWN事件

set repeat 函数,该函数采用一个值作为键重复之前的初始延迟值,以及一个用于重复键之间的延迟的值。这两个值都以毫秒为单位(1,000 毫秒/秒)。您可以通过调用不带参数的set_repeat来禁用键重复。皮游戏。.key。name- 此函数采用 KEY 常量并返回该值的描述性字符串。它对于调试很有用,因为当代码运行时,我们只能看到键常量的值,而看不到它的名称。例如,如果我为值为 103 的键获取 KEY DOWN 事件,则可以使用 key。name 以打印出密钥的名称(在本例中为“g”)。

使用按键进行定向移动

您可以使用键盘在屏幕上移动子画面,方法是为向上、向下、向左和向右分配一个键。任何键都可用于方向移动,但要使用的最明显的键是光标键,因为它们是为定向运动而设计的,并且位于正确的位置,可以用一只手进行操作。第一人称射击游戏的粉丝也习惯于使用W,A,S和D键来移动。

那么,我们如何将按键转换为定向运动呢?与大多数类型的运动一样,我们需要创建一个指向我们想要去的方向的航向向量。如果只按下四个方向键中的一个,则航向矢量非常简单。表 6-1 列出了四个基本方向向量。

image.png

除了水平和垂直移动之外,我们希望用户能够通过同时按两个键来对角线移动。例如,如果按下“向上”和“向右”键,则 sprite 应沿对角线向屏幕右上角移动。我们可以通过添加两个简单向量来创建这个对角线向量。如果我们将 Up (0.0, - 1.0) 和 Right (1.0, 0,0) 相加,我们得到 (1.0, -1.0),它指向上方和右侧,但我们不能将其用作标题向量,因为它不再是单位向量(长度 1)。如果我们将其用作标题向量,我们会发现我们的精灵在对角线上的移动速度比垂直或水平方向更快,这并不是那么有用。

在使用计算出的航向之前,我们应该通过归一化它来将其变回单位向量,这给了我们一个大约(0.707,-0.707)的航向。请参阅图 6-1,了解从简单矢量计算的对角线矢量的直观描述。

image.png

清单 6-2 实现了这种方向运动。运行它时,您会看到一个子画面,可以通过按任意光标键水平或垂直移动,或者通过组合按两个光标键来对角线移动。

如果在不修改 vector2.py 文件的情况下运行清单 6-2,则会发现一个错误,该错误是由尝试将某物除以零而生成的。您可以在规范化方法中处理此问题:

image.png

如果尝试除以零,则 x 和 y 无论如何都必须为零。因此,您可以像前面的例子一样非常容易地解决它。现在我们准备采取行动了:

image.png

image.png

清单 6-2 在计算方向向量时有点作弊。如果按下K_LEFT或K_RIGHT,则将 x 分量设置为 -1 或 +1,如果按下 K_UP 或 K_DOWN,则将 y 分量设置为 -1 或 +1。这给了我们与将两个简单的水平和垂直航向向量相加相同的结果。如果您曾经看到过一个数学快捷方式,可以让您用更少的代码做一些事情,请随时尝试一下 - 游戏开发人员发现他们

积累了许多这样省时的宝石!

您可能已经注意到,只有八个矢量用于此矢量运动。如果我们要预先计算这些向量并将它们直接插入到代码中,我们可以减少运行脚本时完成的工作量。如果您喜欢挑战,那么作为练习是值得的,但是由于计算航向矢量每帧只做一次,因此加快速度不会对帧速率产生明显影响。留意这样的情况;减少游戏创建帧必须完成的工作量称为优化,当有很多动作发生时,它变得更加重要。