用Python和Pygame模块构建一个游戏框架
这系列的***篇通过创建一个简单的骰子游戏来探究 Python。现在是来从零制作你自己的游戏的时间。
在我的这系列的***篇文章 中, 我已经讲解如何使用 Python 创建一个简单的、基于文本的骰子游戏。这次,我将展示如何使用 Python 模块 Pygame 来创建一个图形化游戏。它将需要几篇文章才能来得到一个确实做成一些东西的游戏,但是到这系列的结尾,你将更好地理解如何查找和学习新的 Python 模块和如何从其基础上构建一个应用程序。
在开始前,你必须安装 Pygame。
安装新的 Python 模块
有几种方法来安装 Python 模块,但是最通用的两个是:
- 从你的发行版的软件存储库
- 使用 Python 的软件包管理器
pip
两个方法都工作的很好,并且每一个都有它自己的一套优势。如果你是在 Linux 或 BSD 上开发,可以利用你的发行版的软件存储库来自动和及时地更新。
然而,使用 Python 的内置软件包管理器可以给予你控制更新模块时间的能力。而且,它不是特定于操作系统的,这意味着,即使当你不是在你常用的开发机器上时,你也可以使用它。pip
的其它的优势是允许本地安装模块,如果你没有正在使用的计算机的管理权限,这是有用的。
使用 pip
如果 Python 和 Python3 都安装在你的系统上,你想使用的命令很可能是 pip3
,它用来区分 Python 2.x 的 pip
的命令。如果你不确定,先尝试 pip3
。
pip
命令有些像大多数 Linux 软件包管理器一样工作。你可以使用 search
搜索 Python 模块,然后使用 install
安装它们。如果你没有你正在使用的计算机的管理权限来安装软件,你可以使用 --user
选项来仅仅安装模块到你的家目录。
<span class="pln">$ pip3 search pygame</span>
<span class="pun">[...]</span>
<span class="typ">Pygame</span><span class="pln"> </span><span class="pun">(</span><span class="lit">1.9</span><span class="pun">.</span><span class="lit">3</span><span class="pun">)</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="typ">Python</span><span class="pln"> </span><span class="typ">Game</span><span class="pln"> </span><span class="typ">Development</span>
<span class="pln">sge</span><span class="pun">-</span><span class="pln">pygame </span><span class="pun">(</span><span class="lit">1.5</span><span class="pun">)</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> A </span><span class="lit">2</span><span class="pun">-</span><span class="pln">D game engine </span><span class="kwd">for</span><span class="pln"> </span><span class="typ">Python</span>
<span class="pln">pygame_camera </span><span class="pun">(</span><span class="lit">0.1</span><span class="pun">.</span><span class="lit">1</span><span class="pun">)</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> A </span><span class="typ">Camera</span><span class="pln"> lib </span><span class="kwd">for</span><span class="pln"> </span><span class="typ">PyGame</span>
<span class="pln">pygame_cffi </span><span class="pun">(</span><span class="lit">0.2</span><span class="pun">.</span><span class="lit">1</span><span class="pun">)</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> A cffi</span><span class="pun">-</span><span class="pln">based SDL wrapper that copies the pygame API</span><span class="pun">.</span>
<span class="pun">[...]</span>
<span class="pln">$ pip3 install </span><span class="typ">Pygame</span><span class="pln"> </span><span class="pun">--</span><span class="pln">user</span>
Pygame 是一个 Python 模块,这意味着它仅仅是一套可以使用在你的 Python 程序中的库。换句话说,它不是一个像 IDLE 或 Ninja-IDE 一样可以让你启动的程序。
Pygame 新手入门
一个电子游戏需要一个背景设定:故事发生的地点。在 Python 中,有两种不同的方法来创建你的故事背景:
- 设置一种背景颜色
- 设置一张背景图片
你的背景仅是一张图片或一种颜色。你的电子游戏人物不能与在背景中的东西相互作用,因此,不要在后面放置一些太重要的东西。它仅仅是设置装饰。
设置你的 Pygame 脚本
要开始一个新的 Pygame 工程,先在计算机上创建一个文件夹。游戏的全部文件被放在这个目录中。在你的工程文件夹内部保持所需要的所有的文件来运行游戏是极其重要的。
一个 Python 脚本以文件类型、你的姓名,和你想使用的许可证开始。使用一个开放源码许可证,以便你的朋友可以改善你的游戏并与你一起分享他们的更改:
<span class="com">#</span><span class="pun">!</span><span class="str">/usr/</span><span class="pln">bin</span><span class="pun">/</span><span class="kwd">env</span><span class="pln"> python3</span>
<span class="com">#</span><span class="pln"> by </span><span class="typ">Seth</span><span class="pln"> </span><span class="typ">Kenlon</span>
<span class="com">##</span><span class="pln"> </span><span class="typ">GPLv3</span>
<span class="com">#</span><span class="pln"> </span><span class="typ">This</span><span class="pln"> program </span><span class="kwd">is</span><span class="pln"> free software</span><span class="pun">:</span><span class="pln"> you can redistribute it </span><span class="kwd">and</span><span class="pun">/</span><span class="kwd">or</span>
<span class="com">#</span><span class="pln"> modify it under the terms of the GNU </span><span class="typ">General</span><span class="pln"> </span><span class="typ">Public</span><span class="pln"> </span><span class="typ">License</span><span class="pln"> </span><span class="kwd">as</span>
<span class="com">#</span><span class="pln"> published by the </span><span class="typ">Free</span><span class="pln"> </span><span class="typ">Software</span><span class="pln"> </span><span class="typ">Foundation</span><span class="pun">,</span><span class="pln"> either version </span><span class="lit">3</span><span class="pln"> of the</span>
<span class="com">#</span><span class="pln"> </span><span class="typ">License</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">or</span><span class="pln"> </span><span class="pun">(</span><span class="pln">at your option</span><span class="pun">)</span><span class="pln"> any later version</span><span class="pun">.</span>
<span class="com">#</span>
<span class="com">#</span><span class="pln"> </span><span class="typ">This</span><span class="pln"> program </span><span class="kwd">is</span><span class="pln"> distributed </span><span class="kwd">in</span><span class="pln"> the hope that it will be useful</span><span class="pun">,</span><span class="pln"> but</span>
<span class="com">#</span><span class="pln"> WITHOUT ANY WARRANTY</span><span class="pun">;</span><span class="pln"> without even the implied warranty of</span>
<span class="com">#</span><span class="pln"> MERCHANTABILITY </span><span class="kwd">or</span><span class="pln"> FITNESS FOR A PARTICULAR PURPOSE</span><span class="pun">.</span><span class="pln"> </span><span class="typ">See</span><span class="pln"> the GNU</span>
<span class="com">#</span><span class="pln"> </span><span class="typ">General</span><span class="pln"> </span><span class="typ">Public</span><span class="pln"> </span><span class="typ">License</span><span class="pln"> </span><span class="kwd">for</span><span class="pln"> </span><span class="kwd">more</span><span class="pln"> details</span><span class="pun">.</span>
<span class="com">#</span>
<span class="com">#</span><span class="pln"> </span><span class="typ">You</span><span class="pln"> should have received a copy of the GNU </span><span class="typ">General</span><span class="pln"> </span><span class="typ">Public</span><span class="pln"> </span><span class="typ">License</span>
<span class="com">#</span><span class="pln"> along </span><span class="kwd">with</span><span class="pln"> </span><span class="kwd">this</span><span class="pln"> program</span><span class="pun">.</span><span class="pln"> </span><span class="typ">If</span><span class="pln"> </span><span class="kwd">not</span><span class="pun">,</span><span class="pln"> see </span><span class="pun"><</span><span class="pln">http</span><span class="pun">:</span><span class="com">//www.gnu.org/licenses/>.</span>
然后,你告诉 Python 你想使用的模块。一些模块是常见的 Python 库,当然,你想包括一个你刚刚安装的 Pygame 模块。
<span class="kwd">import</span><span class="pln"> pygame </span><span class="com">#</span><span class="pln"> </span><span class="pun">加载</span><span class="pln"> pygame </span><span class="pun">关键字</span>
<span class="kwd">import</span><span class="pln"> sys </span><span class="com">#</span><span class="pln"> </span><span class="pun">让</span><span class="pln"> python </span><span class="pun">使用你的文件系统</span>
<span class="kwd">import</span><span class="pln"> os </span><span class="com">#</span><span class="pln"> </span><span class="pun">帮助</span><span class="pln"> python </span><span class="pun">识别你的操作系统</span>
由于你将用这个脚本文件做很多工作,在文件中分成段落是有帮助的,以便你知道在哪里放代码。你可以使用块注释来做这些,这些注释仅在看你的源文件代码时是可见的。在你的代码中创建三个块。
<span class="str">'''</span>
<span class="str">Objects</span>
<span class="str">'''</span>
<span class="com">#</span><span class="pln"> </span><span class="pun">在这里放置</span><span class="pln"> </span><span class="typ">Python</span><span class="pln"> </span><span class="pun">类和函数</span>
<span class="str">'''</span>
<span class="str">Setup</span>
<span class="str">'''</span>
<span class="com">#</span><span class="pln"> </span><span class="pun">在这里放置一次性的运行代码</span>
<span class="str">'''</span>
<span class="str">Main Loop</span>
<span class="str">'''</span>
<span class="com">#</span><span class="pln"> </span><span class="pun">在这里放置游戏的循环代码指令</span>
接下来,为你的游戏设置窗口大小。注意,不是每一个人都有大计算机屏幕,所以,***使用一个适合大多数人的计算机的屏幕大小。
这里有一个方法来切换全屏模式,很多现代电子游戏都会这样做,但是,由于你刚刚开始,简单起见仅设置一个大小即可。
<span class="str">'''</span>
<span class="str">Setup</span>
<span class="str">'''</span>
<span class="pln">worldx </span><span class="pun">=</span><span class="pln"> </span><span class="lit">960</span>
<span class="pln">worldy </span><span class="pun">=</span><span class="pln"> </span><span class="lit">720</span>
在脚本中使用 Pygame 引擎前,你需要一些基本的设置。你必须设置帧频,启动它的内部时钟,然后开始 (init
)Pygame 。
<span class="pln">fps </span><span class="pun">=</span><span class="pln"> </span><span class="lit">40</span><span class="pln"> </span><span class="com">#</span><span class="pln"> </span><span class="pun">帧频</span>
<span class="pln">ani </span><span class="pun">=</span><span class="pln"> </span><span class="lit">4</span><span class="pln"> </span><span class="com">#</span><span class="pln"> </span><span class="pun">动画循环</span>
<span class="pln">clock </span><span class="pun">=</span><span class="pln"> pygame</span><span class="pun">.</span><span class="kwd">time</span><span class="pun">.</span><span class="typ">Clock</span><span class="pun">()</span>
<span class="pln">pygame</span><span class="pun">.</span><span class="kwd">init</span><span class="pun">()</span>
现在你可以设置你的背景。
设置背景
在你继续前,打开一个图形应用程序,为你的游戏世界创建一个背景。在你的工程目录中的 images
文件夹内部保存它为 stage.png
。
这里有一些你可以使用的自由图形应用程序。
- Krita 是一个专业级绘图素材模拟器,它可以被用于创建漂亮的图片。如果你对创建电子游戏艺术作品非常感兴趣,你甚至可以购买一系列的游戏艺术作品教程。
- Pinta 是一个基本的,易于学习的绘图应用程序。
- Inkscape 是一个矢量图形应用程序。使用它来绘制形状、线、样条曲线和贝塞尔曲线。
你的图像不必很复杂,你可以以后回去更改它。一旦有了它,在你文件的 Setup 部分添加这些代码:
<span class="pln">world </span><span class="pun">=</span><span class="pln"> pygame</span><span class="pun">.</span><span class="pln">display</span><span class="pun">.</span><span class="pln">set_mode</span><span class="pun">([</span><span class="pln">worldx</span><span class="pun">,</span><span class="pln">worldy</span><span class="pun">])</span>
<span class="pln">backdrop </span><span class="pun">=</span><span class="pln"> pygame</span><span class="pun">.</span><span class="pln">image</span><span class="pun">.</span><span class="pln">load</span><span class="pun">(</span><span class="pln">os</span><span class="pun">.</span><span class="pln">path</span><span class="pun">.</span><span class="kwd">join</span><span class="pun">(</span><span class="str">'images'</span><span class="pun">,</span><span class="str">'stage.png'</span><span class="pun">).</span><span class="pln">convert</span><span class="pun">())</span>
<span class="pln">backdropbox </span><span class="pun">=</span><span class="pln"> world</span><span class="pun">.</span><span class="pln">get_rect</span><span class="pun">()</span>
如果你仅仅用一种颜色来填充你的游戏的背景,你需要做的就是:
<span class="pln">world </span><span class="pun">=</span><span class="pln"> pygame</span><span class="pun">.</span><span class="pln">display</span><span class="pun">.</span><span class="pln">set_mode</span><span class="pun">([</span><span class="pln">worldx</span><span class="pun">,</span><span class="pln">worldy</span><span class="pun">])</span>
你也必须定义颜色以使用。在你的 Setup 部分,使用红、绿、蓝 (RGB) 的值来创建一些颜色的定义。
<span class="str">'''</span>
<span class="str">Setup</span>
<span class="str">'''</span>
<span class="pln">BLUE </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">25</span><span class="pun">,</span><span class="lit">25</span><span class="pun">,</span><span class="lit">200</span><span class="pun">)</span>
<span class="pln">BLACK </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">23</span><span class="pun">,</span><span class="lit">23</span><span class="pun">,</span><span class="lit">23</span><span class="pln"> </span><span class="pun">)</span>
<span class="pln">WHITE </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="lit">254</span><span class="pun">,</span><span class="lit">254</span><span class="pun">,</span><span class="lit">254</span><span class="pun">)</span>
至此,你理论上可以启动你的游戏了。问题是,它可能仅持续了一毫秒。
为证明这一点,保存你的文件为 your-name_game.py
(用你真实的名称替换 your-name
)。然后启动你的游戏。
如果你正在使用 IDLE,通过选择来自 “Run” 菜单的 “Run Module” 来运行你的游戏。
如果你正在使用 Ninja,在左侧按钮条中单击 “Run file” 按钮。
你也可以直接从一个 Unix 终端或一个 Windows 命令提示符中运行一个 Python 脚本。
<span class="pln">$ python3 </span><span class="pun">./</span><span class="pln">your</span><span class="pun">-</span><span class="pln">name_game</span><span class="pun">.</span><span class="pln">py</span>
如果你正在使用 Windows,使用这命令:
<span class="pln">py</span><span class="pun">.</span><span class="pln">exe your</span><span class="pun">-</span><span class="pln">name_game</span><span class="pun">.</span><span class="pln">py</span>
启动它,不过不要期望很多,因为你的游戏现在仅仅持续几毫秒。你可以在下一部分中修复它。
循环
除非另有说明,一个 Python 脚本运行一次并仅一次。近来计算机的运行速度是非常快的,所以你的 Python 脚本运行时间会少于 1 秒钟。
为强制你的游戏来处于足够长的打开和活跃状态来让人看到它(更不要说玩它),使用一个 while
循环。为使你的游戏保存打开,你可以设置一个变量为一些值,然后告诉一个 while
循环只要变量保持未更改则一直保存循环。
这经常被称为一个“主循环”,你可以使用术语 main
作为你的变量。在你的 Setup 部分的任意位置添加代码:
<span class="pln">main </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">True</span>
在主循环期间,使用 Pygame 关键字来检查键盘上的按键是否已经被按下或释放。添加这些代码到你的主循环部分:
<span class="str">'''</span>
<span class="str">Main Loop</span>
<span class="str">'''</span>
<span class="kwd">while</span><span class="pln"> main </span><span class="pun">==</span><span class="pln"> </span><span class="kwd">True</span><span class="pun">:</span>
<span class="pln"> </span><span class="kwd">for</span><span class="pln"> event </span><span class="kwd">in</span><span class="pln"> pygame</span><span class="pun">.</span><span class="pln">event</span><span class="pun">.</span><span class="kwd">get</span><span class="pun">():</span>
<span class="pln"> </span><span class="kwd">if</span><span class="pln"> event</span><span class="pun">.</span><span class="pln">type </span><span class="pun">==</span><span class="pln"> pygame</span><span class="pun">.</span><span class="pln">QUIT</span><span class="pun">:</span>
<span class="pln"> pygame</span><span class="pun">.</span><span class="pln">quit</span><span class="pun">();</span><span class="pln"> sys</span><span class="pun">.</span><span class="kwd">exit</span><span class="pun">()</span>
<span class="pln"> main </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">False</span>
<span class="pln"> </span><span class="kwd">if</span><span class="pln"> event</span><span class="pun">.</span><span class="pln">type </span><span class="pun">==</span><span class="pln"> pygame</span><span class="pun">.</span><span class="pln">KEYDOWN</span><span class="pun">:</span>
<span class="pln"> </span><span class="kwd">if</span><span class="pln"> event</span><span class="pun">.</span><span class="pln">key </span><span class="pun">==</span><span class="pln"> ord</span><span class="pun">(</span><span class="str">'q'</span><span class="pun">):</span>
<span class="pln"> pygame</span><span class="pun">.</span><span class="pln">quit</span><span class="pun">()</span>
<span class="pln"> sys</span><span class="pun">.</span><span class="kwd">exit</span><span class="pun">()</span>
<span class="pln"> main </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">False</span>
也是在你的循环中,刷新你世界的背景。
如果你使用一个图片作为背景:
<span class="pln">world</span><span class="pun">.</span><span class="pln">blit</span><span class="pun">(</span><span class="pln">backdrop</span><span class="pun">,</span><span class="pln"> backdropbox</span><span class="pun">)</span>
如果你使用一种颜色作为背景:
<span class="pln">world</span><span class="pun">.</span><span class="pln">fill</span><span class="pun">(</span><span class="pln">BLUE</span><span class="pun">)</span>
***,告诉 Pygame 来重新刷新屏幕上的所有内容,并推进游戏的内部时钟。
<span class="pln"> pygame</span><span class="pun">.</span><span class="pln">display</span><span class="pun">.</span><span class="pln">flip</span><span class="pun">()</span>
<span class="pln"> clock</span><span class="pun">.</span><span class="pln">tick</span><span class="pun">(</span><span class="pln">fps</span><span class="pun">)</span>