與Python自帶的random、math、time等模塊一樣,Pygame框架也帶有許多模塊來提供繪圖、播放聲音、處理鼠標輸入等功能。
本章將講述Pygame提供的基本模塊及功能,并假設讀者已經具有基本的python編程知識,如果在這方面遇到困難,可閱讀“Ivent Your Own Computer Games ?With Python”這本書。
**GUI和CLI**
使用Python自帶的函數print()和input()來操作文本,你的程序可以將文本顯示在顯示器上并可以讓用戶從鍵盤輸入文本,這類的程序具有命令行界面(command line interface, 簡稱CLI),但它不能顯示圖像、顏色、或者使用鼠標,此類型程序僅通過input()函數接收鍵盤輸入,并當用戶按下回車鍵之后才對輸入進行響應,所以它不適合實時動作游戲的開發。
Pygame提供了編寫用戶圖形界面(graphicaluser interface, 簡稱GUI)程序的功能,來替代基于文本的CLI程序,GUI程序可以顯示具有圖像和顏色的窗口。
**Pygame版本的HelloWorld程序**
我們將使用Pygame編寫一個顯示“Hello World”的窗口程口程序,源碼如下:
~~~
import pygame, sys
from pygame.locals import *
pygame.init()
DISPLAYSURF = pygame.display.set_mode((400, 300))
pygame.display.set_caption('Hello World!')
while True: # main game loop
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
pygame.display.update()
~~~
運行程序,出現如下一個空窗口:

是的,你剛剛制造了世界上最無聊的一個游戲,它僅僅在窗口的標題上顯示了“Hello World”,但創建窗口是圖形界面游戲的第一步,當你點擊窗口右上角的關閉按鈕,程序將會退出,并且窗口消失。
如果調用print()函數來顯示文本在窗口上,它將不能工作,因為print()是CLI程序的函數,input函數也是一樣。Pygame使用其他的函數提供輸入及輸出,這些將在本章的后面講述,讓我們先解讀一下“Hello World”程序每一行的含義。
**建立一個Pygame程序**
此程序中的第一行是幾乎所有pygame程序必備的。
~~~
import pygame, sys
~~~
此行使用import 語句導入程序中要使用的pygame和sys模塊,pygame模塊提供了圖形、聲音等函數。
注意,當你導入了pygame模塊,你將默認地導入了pygame的所有子模塊,例如pygame.images,pygame.mixer.music等,所以沒有必要再導次導入它們。
~~~
from pygame.locals import *
~~~
第2行也是import語句,但它沒有使用import modulename的格式,而使用from modulename import *的格式,通常,如果你要調用一個模塊中的函數,必須使用modulename.functionname()的格式,然而,使用frommodulename improt *的格式,將不用模塊名稱前綴,直接使用函數名稱即可(就像Python內置函數一樣)。
我們導入pygame.locals的原因是因為它包含了許多Pygame提供的常量。from … import *這種格式使我們不用在常量名稱前添加pyame.locals前綴。
~~~
pygame.init()
~~~
第4行調用了pygame.init()函數,它必須在導入pygame模塊之后,且開始使用Pygame提供的任何函數前調用,你不必知道此函數的作用,只需要知道,為了使用pygame函數能正常工作,必須在一開始就調用它。如果你碰到像pygame.error: font not initialized這樣的錯識,請檢查一下是否忘記了在程序前面調用pygame.init()。
~~~
DISPLAYSURF = pygame.display.set_mode((400, 300))
~~~
第5行調用了pygame.display.set_mode()函數,它將返回一個當前窗口的pygame.Surface對象(Surface對象將在本章后面描述),注意,你給函數傳入了一個具有兩個整形值的元組,這個元組通知set_mode()函數當前窗口的寬和高(單位為像素),(400, 300)將建立一個寬400像素、高300像素的窗口。
請記住需要傳遞一個帶有兩個整形的元組類型變量給set_mode()函數,而不是兩個獨立的數字,正確的調用方法是:pygame.display.set_mode((400, 300))。像pygame.display.set_mode(400,300)將產生一個如TypeError: argument 1 must be 2-item sequence, not int的錯誤。
返回的pygame.Surface將被保存在變量DISPLAYSURF中。
~~~
pygame.display.set_caption('Hello World!')
~~~
第6行調用pygame.display.set_caption()來設置標題欄上的文本。
**游戲循環和游戲狀態**
~~~
while True: # main game loop
for event in pygame.event.get():
~~~
第7行是帶了條件為True的while循環語句,它表示一個無限循環,退出循環的方式只有在while循環中使用break語句(使執行重新從while的下一行開始)或者使用sys.exit()函數(它將結束整個程序)。
本書中的所有游戲均具有while True循環,并注明“main game loop”字樣的注釋。一個游戲循環主要做以下三件事情:
1.????????處理事件
2.????????更新游戲狀態
3.????????在屏幕上繪圖
游戲狀態可理解為程序中所有變量的值的集合,在有些游戲中,游戲狀態包括存放人物健康和位置的變量,這些值可以以分數形在屏幕上顯示,如果人物受到傷害,健康值將減少,我們稱這些均為為游戲狀態改變。
保存游戲也是如此,大多數游戲中,暫停表示使用游戲狀態變化停止。
游戲狀態通常隨事件的發生而改變,例如鼠標點擊、鍵盤輸入、或者時間的流失,游戲循環在一秒中執行多次來不挺地檢查是否有新事件產生,并且會根據事件來更新游戲狀態,這通常叫做事件處理。

**pygame.event.Event 對象**
用戶可能會不時地做一些操作,如按鍵、在窗口中移動鼠標,這時,一個pygame.event.Event對象將產生,此對象定義在pygame.event模塊中,可以使用pygame.event.get()函數來捕獲這些事件,這將返回一個pygame.event.Event對象的列表。這個列表中包含了pygame.event.Event函數調用后的所有事件。
~~~
while True: # main game loop
for event in pygame.event.get():
~~~
第8行將pygame.event.get()捕獲到的事件逐一取出并賦值給event變量,例如用戶點擊了鼠標并且按鍵,鼠標點擊事件將先返回,緊接著按鍵事件返回,如果沒有事件產生,pygame.event.get將返回一個空的列表。
**QUIT事件和pygame.quit()函數**
~~~
if event.type == QUIT:
pygame.quit()
sys.exit()
~~~
Event對象具有一些表示事件的成員變量(或者稱為屬性),第9行檢查如果事件對象的類型是否為QUIT,記住,我們使用了from pygame.locals improt *的格式,這樣將可以用QUIT來替代pyame.locals.QUIT? 這種形式。
如果事件類型為退出,將調用pygame.quit()和sys.exit()函數,pygame.quit()與pygame.init()作用相反,它將注銷pygame庫,程序應該在調用sys.exit()前調用pygame.quit()。
我們沒有使用if語句來處理其他的事件,例如鼠標點擊、按鍵等,所以這些事件雖然會產生,但程序不做處理。
~~~
pygame.display.update()
~~~
第12行調用pygame.display.update()函數來繪制由pygame.display.set_mode()函數返回的Surface對象,如果Surface對象沒有變化,每次調用pygame.dispaly.update()時一個空白的圖像將會在屏幕上繪制。
整個程序講解完畢,除過顯示一個空白窗口在屏幕上之外,此程序什么都沒做,接下來我們將學習如何在窗口上顯示一些有趣的東西,在這之前,需要了解像素、Surface 對象、Color對象、Rect對象,以用pygame的繪圖函數。
注:最近計劃翻譯Sweigart的《Making Games with Python & Pygame》這本書,所有內容會依據進度發布與此博客。原書可在[http://inventwithpython.com/](http://inventwithpython.com/)上找到。
- 前言
- Python:實現文件歸檔
- Pyhon:按行輸出文件內容
- Python:讀文件和寫文件
- Python:實現一個小算法
- Python:通過命令行發送新浪微博
- Python:通過攝像頭實現的監控功能
- Python:通過攝像頭抓取圖像并自動上傳至新浪微博
- Python:簡單的攝像頭程序實現
- Python:日志模塊logging的應用
- Python:操作嵌入式數據庫SQLite
- Python:將句子中的單詞全部倒排過來,但單詞的字母順序不變
- Python:語音處理,實現在線朗讀RFC文檔或本地文本文件
- Python:通過計算階乘來學習lambda和reduce這兩個函數的使用
- Python:通過執行100萬次打印來比較C和python的性能,以及用C和python結合來解決性能問題的方法
- Python:使用matplotlib繪制圖表
- Python:使用pycha快速繪制辦公常用圖(餅圖、垂直直方圖、水平直方圖、散點圖等七種圖形)
- Python:使用pycha快速繪制辦公常用圖二(使用樣式定制個性化圖表)
- Python:監控鍵盤輸入、鼠標操作,并將捕獲到的信息記錄到文件中
- Python:通過獲取淘寶賬號和密碼的實驗,來看登陸方式選擇的重要性
- Python:通過獲取淘寶賬號和密碼的實驗,來看登陸方式選擇的重要性(二)
- Python:通過遠程監控用戶輸入來獲取淘寶賬號和密碼的實驗(一)
- Python:通過遠程監控用戶輸入來獲取淘寶賬號和密碼的實驗(二)
- Python:通過自定義系統級快捷鍵來控制程序運行
- Python:通過自定義系統級快捷鍵來控制程序開始或停止記錄日志(使用小技巧解決一個貌似無解的問題)
- Python:一個多功能的抓圖工具開發(附源碼)
- Python:程序發布方式簡介一(打包為可執行文件EXE)
- Python:新浪微博應用開發簡介(認證及授權部分)
- Python:程序最小化到托盤功能實現
- Python:實用抓圖工具開發介紹(含需求分析、設計、編碼、單元測試、打包、系統測試、發布各環節)
- Python:桌面氣泡提示功能實現
- Python:未來三個月的python學習計劃
- Python:pygame模塊及SDL庫簡介
- Python:獲取新浪微博用戶的收聽列表和粉絲列表
- Python:pygame游戲編程之旅一(Hello World)
- Python:pygame游戲編程之旅二(自由移動的小球)
- Python:pygame游戲編程之旅三(玩家控制的小球)
- Python:pygame游戲編程之旅四(游戲界面文字處理)
- Python:pygame游戲編程之旅五(游戲界面文字處理詳解)
- Python:pygame游戲編程之旅六(游戲中的聲音處理)
- Python:pygame游戲編程之旅七(pygame基礎知識講解1)
- Python:編程“八榮八恥”之我見
- Python:腳本的幾種執行方式
- wxPython:簡單的wxPython程序
- wxPython:簡單的wxPython程序的另一種寫法
- wxPython:應用程序對象介紹
- wxPython:輸出重定向
- wxPython:關閉wxPython程序
- wxPython:Frame類介紹
- wxPython:面板Panel的使用
- wxPython:工具欄、狀態欄、菜單實現
- wxPython:消息對話框MessageDialog
- wxPython:文本對話框TextEntryDialog
- wxPython:列表選擇框SingleChoiceDialog
- wxPython:事件處理介紹一
- wxPython:事件處理介紹二
- wxPython: 簡單的繪圖例子
- wxPython:狀態欄介紹
- wxPython:菜單介紹
- wxPython:文件對話框wx.FileDialog
- wxPython:顏色選擇對話框wx.ColourDialog
- wxPython:布局管理器sizer介紹
- wxPython:啟動畫面SplashScreen介紹
- wxPython:繪畫按鈕BitmapButton介紹
- wxPython:進度條Gauge介紹
- Python: 發送新浪微博(使用oauth2)
- Python:讀取新浪微博收聽列表
- Python:DNS客戶端實現