Pygame 官方文档 - Tutorials - 逐行的黑猩猩教程(Line By Line Chimp)
逐行的黑猩猩教程(Line By Line Chimp)
作者: Pete Shinners
聯系方式: pete@shinners.org
介紹(Introduction)
? ? ? ?在pygame示例中,有一個名為“黑猩猩”的簡單示例。這個例子模擬了一只可被打的猴子在一個小屏幕上走動,并且承諾有財富和回報。示例本身非常簡單,并且在錯誤檢查代碼上有點單薄。這個示例程序演示了許多pygame的功能,如創建圖形窗口,加載圖像和聲音文件,渲染TTF文本以及基本事件和鼠標處理。
? ? ? ?這個程序和圖像可以在pygame的標準源代碼發布中找到。對于pygame的1.3版本,此示例已完全重寫,以添加更多功能并更正錯誤檢查。這大約是原始示例大小的兩倍,但現在給我們提供了更多可查看的內容,以及我可以建議您自己的項目可以重用的代碼。
本教程將逐塊瀏覽代碼。解釋代碼的工作原理。還將提到如何改進代碼以及錯誤檢查可以提供哪些幫助。
? ? ? ?這是一個很好的教程,特別對于第一次看到pygame代碼的人。一旦完全安裝了pygame,您就可以在examples目錄中找到并運行自己的黑猩猩演示。
導入模塊(Import Modules)
這是將所有需要的模塊導入程序的代碼。 它還檢查一些可選的pygame模塊的可用性。
? ? ? ?首先,我們導入標準的“os”和“sys”python模塊。這些允許我們做一些事情,比如創建獨立于平臺的文件路徑
? ? ? ?在下一行中,我們導入pygame包。導入pygame時,它會導入屬于pygame的所有模塊。一些pygame模塊是可選的,如果找不到它們,它們的值將設置為“None”。
? ? ? ?有一個名為“locals”的特殊pygame模塊。該模塊包含pygame的子集。該模塊的成員是常用的常量和函數,已證明將其放入程序的全局命名空間中是有用的。這個locals模塊包括像“Rect”這樣的函數來創建一個矩形對象,以及許多常量,如“QUIT,HWSURFACE”,用于與其余的pygame交互。像這樣將locals模塊導入全局命名空間是完全可選的。如果您選擇不導入它,則局部作用域下的所有成員始終在pygame模塊中可用。
? ? ? ?最后,如果pygame中的字體或聲音模塊不可用,我們決定打印一條很棒的警告消息。
加載資源(Loading Resource)
這里我們有兩個函數可以用來加載圖像和聲音。 我們將在本節中單獨查看每個功能。
? ? ? ?此函數可以傳入要加載的圖像的名稱。它還可以選擇使用一個參數來設置圖像的顏色鍵。在圖形中使用顏色鍵來表示透明圖像的顏色。
此函數的第一件事是創建文件的完整路徑名。在此示例中,所有資源都位于“data”子目錄中。通過使用os.path.join函數,將創建一個路徑名,該路徑名適用于運行游戲的任何平臺。
? ? ? ?接下來,我們使用pygame.image.load函數加載圖像。我們將此函數包裝在try / except塊中,因此如果加載圖像時出現問題,我們可以正常退出。加載圖像后,我們對convert()函數進行了重要調用。這將生成Surface的新副本并轉換其顏色格式和深度以匹配顯示。這意味著將圖像blitting 到屏幕將盡快的發生。
? ? ? ?最后,我們為圖像設置了colorkey。如果用戶為colorkey參數提供了參數,我們將該值用作圖像的顏色鍵。這通常只是一個顏色RGB值,如白色(255,255,255)。您還可以傳遞值-1作為顏色鍵。在這種情況下,該函數將在圖像的左上角像素處查找顏色,并將該顏色用于colorkey。
? ? ? ?接下來是加載聲音文件的功能。 這個函數做的第一件事是檢查是否正確導入了pygame.mixer模塊。 如果沒有,它返回一個虛擬播放方法(dummy play method)的小類實例。 這將足夠像一個正常的聲音對象使這個游戲運行,沒有任何額外的錯誤檢查。
? ? ? ?此函數類似于圖像加載功能,但處理一些不同的問題。 首先,我們創建聲音圖像的完整路徑,并將聲音文件加載到try / except語句塊中。 然后我們只簡單地返回加載的Sound對象。
游戲對象的類(Game Object Classes)
? ? ? ?這里我們創建兩個類來表示游戲中的對象。 幾乎游戲的所有邏輯都進入了這兩個類。 我們將在這里一次一個地查看它們。
? ? ? ?在這里我們創建一個代表玩家拳頭的類。它源生自pygame.sprite模塊中包含的Sprite類。創建此類的新實例時,將調用__init__函數。我們要做的第一件事是確保為我們的基類調用__init__函數。這允許Sprite的__init__函數準備我們的對象以用作精靈。這個游戲使用一個精靈繪圖組類(sprite drawing Group classes)。這些類可以繪制具有“image”和“rect”屬性的精靈。通過簡單地更改這兩個屬性,渲染器(renderer)將在當前位置繪制當前圖像。
? ? ? ?所有精靈都有一個update()方法。此功能通常每幀調用一次。在這里你應該放置代碼來移動和更新sprite的變量。用于拳頭的update()方法將拳頭移動到鼠標指針的位置。如果拳頭處于“出拳”狀態,它也會略微抵消拳頭位置。
? ? ? ?以下兩個函數punch()和unpunch()改變拳頭的出拳狀態。如果拳頭與給定的目標精靈碰撞,則punch()方法也會返回true值。
? ? ? ?黑猩猩類的要做的工作比拳頭多一點,但并沒有更加復雜。這個類將在屏幕上來回移動黑猩猩。當猴子被拳頭打中時,他會旋轉到令人興奮的效果。這個類也源生自基礎的Sprite類,并初始化與拳頭類相同。在初始化時,類還將屬性“area”設置為顯示屏幕的大小。
? ? ? ?黑猩猩的update函數只是查看當前的“頭暈”狀態,當猴子被拳擊中旋轉時返回True。它調用_spin或_walk方法。這些函數以下劃線為前綴。這只是一個標準的python習語,它表明這些方法只能由Chimp類使用。我們甚至可以給它們一個雙下劃線,這將告訴python真正嘗試使它們成為私有方法,但我們不需要這樣的保護。 ?
? ? ? ?walk方法通過將當前rect移動給定的偏移量來為猴子創建一個新位置。如果此新位置越過屏幕的顯示區域,則會反轉移動偏移量。它還使用pygame.transform.flip函數鏡像圖像。這是一種粗糙的效果,使猴子看起來像是在轉動他正在移動的方向。
? ? ? ?當猴子目前“頭暈”時調用spin方法。 dizzy屬性被用于存儲當前的旋轉量。當猴子一直旋轉(360度)時,它會將猴子圖像重置回原始的非旋轉版本。在調用transform.rotate函數之前,您將看到代碼對名為“rotate”的函數進行局部引用。對于這個例子沒有必要這樣做,這里只是為了保持以下行的長度更短。請注意,調用旋轉功能時,我們始終從原始猴子圖像旋轉。旋轉時,質量略有下降。反復旋轉相同的圖像,每次質量都會變差。此外,旋轉圖像時,圖像的大小實際上會發生變化。這是因為圖像的角將旋轉出來,使圖像更大。我們確保新圖像的中心與舊圖像的中心匹配,因此它不會移動而旋轉。
? ? ? ?最后一個方法是punched(),它告訴精靈進入其暈眩狀態。這將導致圖像開始旋轉。它還制作了名為“original”的當前圖像的副本。
初始化所有東西(Initialize Everything)
? ? ? ?在我們可以對pygame做很多事情之前,我們需要確保它的模塊已初始化。 在這種情況下,我們還將打開一個簡單的圖形窗口。 現在我們在程序的main()函數中,它實際上運行了所有東西。
? ? ? ?第一行的初始化pygame的為我們完成了一些工作。它檢查導入的pygame模塊并嘗試初始化它們中的每一個。可以返回并檢查模塊是否未能初始化,但我們不會在這里費事。也可以采取更多控制并手動初始化每個特定模塊。通常不需要這種類型的控制,但如果您愿意,可以使用。
? ? ? ?接下來我們設置顯示圖形模式。請注意,pygame.display模塊用于控制所有顯示設置。在這種情況下,我們要求一個簡單的瘦窗口。有關于設置圖形模式的完整單獨教程,但如果我們真的不在乎, pygame會很好地為我們提供有用的東西。 Pygame將選擇最佳顏色深度,因為我們沒有提供。
? ? ? ?最后我們設置窗口標題并關閉窗口的鼠標光標。非常基本的事情,現在我們有一個小黑窗口準備做我們的吩咐的事。通常光標默認為可見,因此除非我們想隱藏它,否則無需真正設置狀態。
創建背景(Create The Background)
? ? ? ?我們的程序在背景上有文本信息。 我們很高興創建一個surface對象來表示背景并重復使用它。
第一步是創建surface對象。
? ? ? ?這為我們創建了一個與顯示窗口大小相同的新surface對象。 注意創建Surface對象后額外調用convert()。 沒有參數的轉換將確保我們的背景與顯示窗口的格式相同,這將為我們提供最快的結果。
? ? ? ?我們還將整個背景填充為純白色。 填充采用RGB三元組作為顏色參數。
把文字放在背景上并居中(Put Text On The Background, Centered)
if pygame.font:font = pygame.font.Font(None, 36)text = font.render("Pummel The Chimp, And Win $$$", 1, (10, 10, 10))textpos = text.get_rect(centerx=background.get_width()/2) background.blit(text, textpos)? ? ? ?如您所見,完成此操作有幾個步驟。首先,我們必須創建字體對象并將其渲染到新的surface對象。然后我們找到新surface對象的中心并將其blit(粘貼)到背景上。
? ? ? ?使用字體模塊的Font()構造函數創建字體。通常,您會將TrueType字體文件的名稱傳遞給此函數,但我們也可以傳遞None,它將使用默認字體。 Font構造函數還需要知道我們想要創建的字體大小。
? ? ? ?然后,我們將該字體渲染為新的surface對象。render函數創建一個適合文本大小的新surface對象。在這種情況下,我們還告訴reander創建抗鋸齒文本(為了一個漂亮的光滑外觀)和使用深灰色。
? ? ? ?接下來,我們需要在顯示屏上找到文本的居中位置。我們從文本尺寸創建一個“Rect”對象,這使我們可以輕松地將其分配給屏幕中心。
最后我們將文本blit(blit就像復制或粘貼)到背景圖像上。
設定完成后顯示背景(Display The Background While Setup Finishes)
我們屏幕上仍然有一個黑色的窗口。讓我們等待其他資源加載時顯示我們的背景。
? ? ? ?這會將我們的整個背景blit到顯示窗口上。 這個blit是不言自明的,但是這個翻轉(flip)行為呢?
? ? ? ?在pygame中,對用于顯示surface對象的更改不會立即可見。 通常,必須在已更改的區域中更新顯示以使其對用戶可見。 使用雙緩沖顯示器時,必須交換(或翻轉)顯示以使更改變得可見。 在這種情況下,flip()函數可以很好地工作,因為它只處理整個窗口區域并處理單緩沖和雙緩沖表面。
準備游戲對象(Prepare Game Object)
在這里,我們創建了游戲所需的所有對象。
? ? ? ?首先,我們使用上面定義的load_sound函數加載兩個聲音效果。 然后我們創建每個sprite類的實例。 最后我們創建了一個sprite Group,它將包含我們所有的sprite。
? ? ? ?我們實際上使用了一個名為RenderPlain的特殊精靈組。 該精靈組可以將它包含的所有精靈繪制到屏幕上。 它被稱為RenderPlain,因為實際上有更高級的Render組。 但對于我們的游戲,我們只需要簡單的繪圖。 我們通過傳遞一個包含應該屬于該組的所有精靈的列表來創建名為“allsprites”的組。 我們以后可以在這個組中添加或刪除精靈,但在這個游戲中我們不需要。
? ? ? ?我們創建的clock對象將用于幫助控制我們游戲的幀速率。 我們將在游戲的主循環中使用它,以確保它不會運行得太快。
主循環(Main Loop)
這里沒什么,只是一個無限循環。
? ? ? ?所有游戲都以某種循環方式運行。 通常的順序是檢查計算機的狀態和用戶輸入,移動并更新所有對象的狀態,然后將它們繪制到屏幕上。 你會看到這個例子并沒有什么不同。
? ? ? ?我們還調用了我們的clock對象,這將確保我們的游戲運行速度不超過每秒60幀。
處理所有輸入事件(Update the Sprite)
這是處理事件隊列的極其簡單的情況。
? ? ? ?首先,我們從pygame獲取所有可用的事件并循環遍歷每個事件。 前兩個測試查看用戶是否已退出游戲,或按下了退出鍵。 在這些情況下,我們只是從main()函數返回,程序干凈地結束。
? ? ? ?接下來,我們只是檢查鼠標按鈕是否被按下或釋放。 如果按下按鈕,我們詢問第一個物體是否與黑猩猩相撞。 我們播放適當的聲音效果,如果猴子被擊中,我們告訴他開始旋轉(通過調用它的punched()方法)。
更新Sprites(Update the Sprites)
allsprites.update()? ? ? ?Sprite組有一個update()方法,它只調用它包含的所有sprite的update方法。 每個物體都會四處移動,具體取決于它們處于哪種狀態。這是黑猩猩將一步一步向一側移動的地方,或者如果他最近被打了一拳則旋轉得更遠。
繪制整個場景(Draw The Entire Scene)
既然所有物體都在正確的位置,那么是時候繪制它們了。
? ? ? ?第一個blit調用將把背景繪制到整個屏幕上。 這會擦除我們從前一幀看到的所有內容(效率稍低,但對于此游戲來說足夠好)。 接下來我們調用sprite容器的draw()方法。 由于這個精靈容器實際上是“DrawPlain”精靈組的一個實例,它知道如何繪制我們的精靈。 最后,我們將pygame的軟件雙緩沖區的內容flip()到屏幕上。 這使得我們繪制的所有內容都可以同時顯示。
游戲結束(Game Over)
? ? ? ?用戶已退出,是時候清理干凈了。在pygame中清理正在運行的游戲非常簡單。 事實上,由于所有變量都被自動破壞,我們真的不需要做任何事情。
?
以上內容,自己翻譯,可能有誤,可參考:Tutorials - 逐行的黑猩猩教程(Line By Line Chimp)
點我回頂部 ?
?
?
?
?
?
?
?
Fin.
總結
以上是生活随笔為你收集整理的Pygame 官方文档 - Tutorials - 逐行的黑猩猩教程(Line By Line Chimp)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中国乡镇企业会计杂志中国乡镇企业会计杂志
- 下一篇: 开源即时通讯软件