开始绘制图形时首先需要建立一个窗口。代码清单 16-1 显示了一个非常简单的程序,它只是创建了一个 Pygame 窗口。
代码清单 16-1 创建一个 Pygame 窗口
import pygamepygame.initscreen = pygame.display.set_mode([640, 480])
试着运行这个程序。你看到了什么?如果仔细看,你可能会看到屏幕非常迅速地弹出了一个窗口(填充为黑色)。这是怎么回事?
嗯,Pygame 的作用就是为了建立游戏。游戏本身不做任何事情,只是与玩家交互。所以 Pygame 有一个事件循环(event loop)不断检查用户在做什么,比如按键或移动鼠标。Pygame 程序需要保持这个事件循环一直运行,只要事件循环停止,程序就停止。在我们的第一个 Pygame 程序中,并没有启动事件循环,所以程序开始后很快就停止了。
没错,不过在 Pygame 中,只有程序运行时窗口才会处于打开状态。所以必须保证程序一直运行。
到底怎么回事?
你是不是很奇怪为什么有时 Pygame 不能与 IDLE 合作?这与事件循环有关。事件循环是一个循环,在程序中一直运行,检查类似按键按下或者鼠标点击或移动之类的事件。Pygame 程序需要有一个事件循环。
IDLE 也有它自己的事件循环,因为它也是一个程序,而且恰好是一个需要不断检查用户输入的图形程序。这两个事件循环并不总能友好相处——它们有时会相互冲突,导致混乱。
对于 IDLE 和 EasyGui 也是一样。这就像有人正在打电话,而你拿起分机也想打电话一样。你根本不能打通电话,因为此时电话正忙。如果你开始讲话或者拨号,就会干扰已经在进行的通话。
SPE 不存在这个问题,因为它有一种办法可以将自己的事件循环与所运行的程序(如你的游戏)的事件循环相分离。
要想保持 Pygame 事件循环一直运行,一种方法是使用 while 循环,类似代码清单 16-2 中的程序。(不过先不要尝试运行!)
代码清单 16-2 保持 Pygame 窗口打开
import pygamepygame.initscreen = pygame.display.set_mode([640, 480])while True: pass
pass 是一个 Python 关键字,表示“什么也不做”。这只是一个占位符,因为 while 循环需要一个代码块,这个块不能为空。(也许你还记得第 8 章中讨论循环时讲到过这个内容)。所以要在 while 块中加点东西,不过这个“东西”什么也不做。
应该记得,只要条件为 True,while 循环就会一直运行。所以这实际上在说,“当 True 为 True 时,保持循环”。因为 True 当然总为 True,所以这意味着永远循环(或者只要程序运行就会一直循环)。
不过,如果它永远运行下去,我们又怎么让它停下来呢?还记得吗?在第 8 章,Carter 问过怎么让一个包含失控循环的程序停下来。我们知道可以用 Ctrl-C 来做到。在这里也可以使用同样的方法。不过,在 Windows 上,如果在 SPE 中运行程序,需要用 Ctrl-Break 而不是 Ctrl-C。这里还有一个小技巧:键入 Ctrl-Break 之前要让命令 shell 窗口成为活动窗口。如果想在 Pygame 窗口中使用 Ctrl-Break,那么什么也不会发生。
在 Mac 上,如果有一个失控循环,应该能按下 Ctrl-C 将它停止。如果不行,可以尝试按下 Ctrl-,发送一个退出信号。或者可以启动活动监视器(Activity Monitor),它位于 Applications 文件夹的 Utilities 文件夹中。找到 Python 或 Pygame 进程,退出这个进程。如果你使用的是 Linux,最容易的方法就是“杀掉”这个进程。
好的,既然知道了怎么让它停止,现在来运行代码清单 16-2 中的程序。可以在你目前使用的任何编辑器中键入这个程序,把它保存为 pygame_1.py。运行时,应该能看到弹出一个新窗口,它有一个黑色背景。窗口标题栏上应该是 pygame window。这个窗口会一直保留,直到你将命令 shell 置为活动窗口,并用 Ctrl-Break 结束程序。
如果从 SPE 运行 Pygame,会打开一个 shell 窗口。这个窗口标题栏上会显示类似 SPE <filename> - Press Ctrl + Break to stop 的标题。想要退出应用之前,需要在这个窗口中点击鼠标,使它变成活动窗口。
更好地结束
要停止我们的 Pygame 程序还有一种更好的方法。你可能已经注意到,Pygame 窗口标题栏右上角有一个 × 图标(就像 Windows 中的大多数窗口一样)。你可能以为这个 × 会关闭窗口 , 在所有其他程序中这确实都能奏效。不过这是我们自己的程序,要由我们来控制,而目前还没有告诉 × 该做什么。下面就来让这个 × 关闭我们的 Pygame 程序。
在一个 Pygame 程序中,× 应该连接到一个名为 sys.exit 的内置函数。这是 Python 标准模块 sys 中的一个函数,告诉程序要退出或停止。我们只需导入 sys 模块,再对代码做一处修改,如代码清单 16-3 所示。
代码清单 16-3 让 Pygame 窗口可以关闭
很快我们就会了解最后 3 行代码是什么意思。对现在来说,只是要做到在我们的所有 Pygame 程序中都包含这几行代码。