首页 » 父与子的编程之旅:与小卡特一起学Python » 父与子的编程之旅:与小卡特一起学Python全文在线阅读

《父与子的编程之旅:与小卡特一起学Python》24.2 Lunar Lander

关灯直达底部

开始时飞船离月球表面有一定距离。月球的重力开始把它向下拉,我们必须使用推进器让它的降落放慢,使它平缓着陆。

这个程序看上去是像下图这样的。

左边的小灰条是推进器。用鼠标上下拖动可以控制发动机的推力。燃料表指出你还剩下多少燃料,上面的文本给出了速度、加速度、高度和推力的有关信息。

模拟着陆

为了模拟飞船着陆,必须理解重力和飞船发动机作用力相互之间如何平衡。

在这个仿真中,我们假设重力是恒定的。事实上并不是这样,不过只要飞船离月球不太远,重力几乎是恒定的(对我们的仿真来说非常接近恒定了)。

术语箱

速度(velocity)与速率“speed”含义几乎是一样的,不过速度还包括方向,而速率不包括方向。例如,“每小时 50 公里”描述的是速率,而“每小时向北 50 公里”描述的就是速度。很多人可能会使用“速率”,但实际上他们所指的是“速度”,反之亦然,有些人谈到“速度”时所指的其实是“速率”。在我们的程序中,我们需要知道飞船是向上还是向下,所以会使用速度。

加速度(acceleration)是指速度变化得多快。正的加速度表示速度在增加,负加速度表示速度在减少。

发动机的作用力取决于燃烧了多少燃料。有时这个作用力会大于重力,有时可能比重力小。发动机关闭时,作用力就为 0,此时只剩下重力。

要得到对飞船的总作用力或净作用力,只需把两个作用力相加。因为它们的方向相反,所以一个为正,另一个为负。

一旦得到飞船上的净作用力,可以利用一个公式得出它的速度和位置。

我们的仿真必须跟踪以下几点。

  • 飞船距离月球的高度,以及飞船的速度和加速度。

  • 飞船的质量(随着燃料的消耗,质量会变化)。

  • 发动机的推力或作用力。使用的推力越大,燃料燃烧得就越快。

  • 飞船上有多少燃料。推进器燃烧燃料时,飞船会变轻,但是如果所有燃料都耗光,就不再有推力。

  • 飞船上的重力。这取决于月球的大小,以及飞船和燃料的质量。

又是 Pygame

我们还是使用 Pygame 建立这个仿真。这里将用 Pygame 的时钟滴答作为我们的时间单位。对于每一个滴答,我们会检查对飞船的净作用力,并更新高度、速度、加速度和剩余的燃料。然后使用这个信息更新图片和文本。

由于动画非常简单,这里不打算用一个动画精灵表示飞船。不过我们会对推进器使用一个精灵(灰色矩形),因为这样就能很容易地用鼠标拖动。燃料表是用 Pygame 的 draw.rect 方法画的两个矩形。文本用 pygame.font 对象建立,就像前面 PyPong 中的做法一样。

代码要完成以下工作。

  • 初始化游戏——建立 Pygame 窗口,加载图像,为变量设置一些初始值。

  • 为推进器定义精灵类。

  • 计算高度、速度、加速度和燃料消耗。

  • 显示这个信息。

  • 更新燃料表。

  • 显示火箭尾焰(取决于推力,尾焰大小会改变)。

  • 把所有内容“块移”(blit)到屏幕,检查鼠标事件,更新推进器位置,并检查飞船是否已经着陆——这就是主 Pygame 事件循环。

  • 显示“游戏结束”和最终统计信息。

代码清单 24-1 显示了 Lunar Lander 的代码,相应的文件是 Listing_24-1.py,可以在 ExamplesLunarLander 文件夹找到这个文件,或者也可以在网站(www.helloworldbook2.com)上找到。在文件夹和网站上还可以找到相关的图片(飞船和月球)。查看代码和说明,一定要确保你能理解所有内容。先不用担心高度、速度和加速度的公式。在高中物理中将会学到这些知识,不过考完试后可能很快就会忘掉(除非你在美国航空航天局工作)。也许这个程序能帮你记住这些公式!

代码清单 24-1 Lunar Lander

试着运行这个程序。没准你会发现自己是一个不错的飞船驾驶员!如果你认为 这太简单了,可以修改代码,让重力更大一些,使飞船更重(质量更大),或者减少 一些燃料,还可以设置一个不同的起始高度或速度。你是程序员,所以游戏该怎么 做由你来决定。

Lunar Lander 仿真主要考虑重力。在本章后面的内容,我们将讨论仿真中另一个 重要的因素——时间。我们会建立一个需要跟踪时间的仿真。