讀古今文學網 > 父與子的編程之旅:與小卡特一起學Python > 24.2 Lunar Lander >

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 仿真主要考慮重力。在本章後面的內容,我們將討論仿真中另一個 重要的因素——時間。我們會建立一個需要跟蹤時間的仿真。