Python游戏编程_植物大战讲僵尸_贪吃蛇
曾經我也沉迷游戲,連續玩十幾個小時競技游戲可以不吃飯。游戲只是別人寫好程序,與其沉迷于他人設計好程序,為何不自己設計游戲,至少學會編程后,我們的月收入上萬不是問題。于是便有了錄制這部[pygame菜鳥游戲編程教程]動力。不要沉迷于游戲,我們人生還有許多事情要做,旅游,找到另一個伴侶,成立一個家庭,照顧父母。。。。
編程正在逐步改變世界,程序員不是搬磚的。但傳統計算教育程面臨枯燥乏味課程,讓學生感到乏味。
興趣是學習最好老師!此課程目的是激發大家對編程興趣,給廣大Python入門初學者帶來無窮樂趣。
游戲涉及童年玩過經典小游戲,包括貪吃蛇,消消樂,俄羅斯方塊,植物大戰僵尸,掃雷等等。視頻的參考資料可下載腳本。腳本已經編譯好,可直接運行!
Have Fun!
歡迎各位同學學習《Python菜鳥快樂游戲編程_pygame》
Python菜鳥快樂游戲編程
下圖展示視頻中幾個經典童年游戲,植物大戰僵尸
《植物大戰僵尸》是由PopCap Games開發的一款益智策略類單機游戲,于2009年5月5日發售。玩家通過武裝多種植物切換不同的功能,快速有效地把僵尸阻擋在入侵的道路上。不同的敵人,不同的玩法構成五種不同的游戲模式,加之黑夜、濃霧以及泳池之類的障礙增加了游戲挑戰性。
《植物大戰僵尸》是一款極富策略性的小游戲。可怕的僵尸即將入侵,每種僵尸都有不同的特點,例如鐵桶僵尸擁有極強的抗擊打能力,礦工僵尸可以挖地道繞過種植在土壤表面的植物等。玩家防御僵尸的方式就是栽種植物。49種植物每種都有不同的功能,例如櫻桃炸彈可以和周圍一定范圍內的所有僵尸同歸于盡,而食人花可以吃掉最靠近自己的一只僵尸。玩家可以針對不同僵尸的弱點來合理地種植植物,這也是勝利的訣竅。游戲根據玩法不同分為五種游戲模式:冒險、生存、花瓶破碎者、小游戲、花園。加之黑夜、屋頂、濃霧以及泳池之類的障礙增加了其挑戰性該游戲近乎永無止境。
奧賽羅棋,人工智能AI范疇,英國每年有比賽
黑白棋,又叫反棋(Reversi)、奧賽羅棋(Othello)、蘋果棋或翻轉棋。黑白棋在西方和日本很流行。游戲通過相互翻轉對方的棋子,最后以棋盤上誰的棋子多來判斷勝負。它的游戲規則簡單,因此上手很容易,但是它的變化又非常復雜。有一種說法是:只需要幾分鐘學會它,卻需要一生的時間去精通它。黑白棋的棋盤是一個有8*8方格的棋盤。把自己顏色的棋子放在棋盤的空格上,而當自己放下的棋子在橫、豎、斜八個方向內有一個自己的棋子,則被夾在中間的全部翻轉會成為自己的棋子。并且,只有在可以翻轉棋子的地方才可以下子。黑白棋是19世紀末英國人發明的。直到上個世紀70年代一個日本人將其發展,借用莎士比亞名劇奧賽羅(othello)為這個游戲重新命名,也就是現在大家玩的黑白棋。為何借用莎士比亞名劇呢?是因為奧賽羅是莎士比亞一個名劇的男主角。他是一個黑人,妻子是白人,因受小人挑撥,懷疑妻子不忠一直情海翻波,最終親手把妻子殺死。后來真相大白,奧賽羅懊悔不已,自殺而死。黑白棋就是借用這個黑人白人斗爭的故事而命名。
游戲期間,位置比點數更重要!要著眼于長遠利益,因為點數的領先很可能是暫時的。四個角上是必須爭取占據的好位置,因為無法移開這些位置上的棋子。 設法使自己走一步時,牽制著對手無法移動任何棋子!這樣可以在一排中連續走兩步。
當然我們沒有必要用一生的時間去精通它。用python程序可以去模擬游戲,找到最佳下棋算法。
開心消消樂,手機玩的很high的爆款游戲
《開心消消樂》是一款樂元素研發的一款三消類休閑游戲。一天晚上,天空中掉下一顆神奇的豌豆種子,正好落在了夢之森林的村長屋附近,種子落地后吸收了池塘的水分,迅速成長,一夜之間變成參天大藤蔓…… 第二天早上,村民們醒來后看到巨大的藤蔓都驚呆了,聚在一起議論紛紛。有人說他似乎看到村長的房子在高聳入云的藤蔓上,房子似乎還在上升,有人號召說應該爬上去救村長,玩家需要爬到藤曼頂部救出村長。
色彩拼圖游戲,AI范疇,基于算法,在規定時間內完成色彩統一,這需要一定思考能力喲。
游戲編程模塊pygame介紹
pygame是一組旨在編寫視頻游戲的Python模塊。Pygame可以使用python語言創建功能齊全的游戲和多媒體程序。Pygame具有高度的可移植性,幾乎可以在所有平臺和操作系統上運行。Pygame至今已被下載了數百萬次。Pygame非常流行的一個原因是免費。 根據LGPL許可證發布的內容,您可以使用它創建開源,免費軟件,共享軟件和商業游戲。Pygame歷史開始于2000年10月。六個月后發布了pygame 1.0版。pygame的目標是使可視化游戲編程變得簡單。 pygame是Python和SDL混合的產物。 SDL由Sam Lantinga創建,與DirectX相比,SDL是用于控制多媒體的跨平臺C庫。它已用于數百種商業和開源游戲。
迫不及待的想用pygame寫一個自己的游戲了嗎?用pip install pygame安裝此模塊吧。
pygame官網
學員查詢pygame模塊基礎語法最好方法是訪問官方文檔,網址為
https://www.pygame.org/docs/ref/surface.html
pygame模塊最常用的對象包括:頂層pygame包,顏色, 顯示,繪畫,事件,字體,圖片,鍵盤,鼠標,常量, 多媒體,矩形, 表面,時間,音樂
高級對象包括:游標,游戲桿, 圖像蒙版,精靈,轉換,計算機字體, 繪制形狀,重疊式展示,像素陣列,像素復制,數學
其他對象包括:相機,音頻CDROM控制,例子,事件和隊列交互, 快速事件,剪貼板支持,測試,觸摸,版本。
pygame 包是可供使用的最頂層的包。Pygame 被分成許多子模塊,但是并不會影響程序使用 Pygame。
pygame常見函數如下:
pygame.init() — 初始化所有導入的 pygame 模塊
pygame.quit() — 卸載所有導入的 pygame 模塊
pygame.error() — 標準 pygame 異常模塊
pygame.get_error() — 獲得當前錯誤信息
pygame.set_error() — 設置當前錯誤信息
pygame.get_sdl_version() — 獲得 SDL 的版本號
pygame.get_sdl_byteorder() — 獲得 SDL 的字節順序
pygame.register_quit() — 注冊一個函數,這個函數將在 pygame 退出時被調用
pygame.encode_string() — 對 unicode 或字節對象編碼
pygame.encode_file_path() — 將 unicode 或字節對象編碼為文件系統路徑
pygame常用對象為:
pygame.Surface表面
pygame.draw繪圖
pygame.font字體
pygame.image圖片
pygame.sprite精靈
pygame.transform轉換
pygame.event事件
pygame.time時間
pygame.mixer.Sound聲音
Pygame語法比較多,且pygame不支持互動shell,不能一行行執行命令,因此最好學習方式是結合游戲實戰編程。我們先用10行代碼就完成第一個pygame游戲窗口,順便了解pygame最主要的語法。
首先輸入import pygame,sys導入具有所有可用pygame模塊的包和系統模塊。
pygame.display.``set_mode()游戲窗口設置
初始化游戲窗口
set_mode(size=(0, 0), flags=0, depth=0, display=0) -> Surface
size參數是一對數字,代表寬度和高度。 flags參數是其他選項的集合。
depth參數代表用于顏色的位數。顏色位數范圍range is {8…32},通常最好不要傳遞depth參數。對于系統,它將默認為最佳和最快的顏色深度。如果您的游戲需要特定的顏色格式,則可以使用此參數控制深度。 Pygame將模擬不可用的顏色深度,該深度可能很慢。
如果我們想要讓游戲窗口在顯示器上全屏展示,我們用pygame.FULLSCREEN對象。
windowSurface=pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT),pygame.FULLSCREEN)
顏色color
pygame.locals
此模塊包含pygame使用的各種常量。 它的內容會自動放置在pygame模塊的命名空間中。 但是,應用程序可以使用pygame.locals僅包含pygame.locals import *的pygame常量。
Event對象有一個名為type的成員變量(member variable,也叫作屬性,attributes或properties),它告訴我們對象表示何種事件。針對pygame.locals模塊中的每一種可能的類型,Pygame都有一個常量變量。第9行檢查Event對象的type是否等于常量QUIT。記住,由于我們使用了from pygame.locals import *形式的import語句,主要輸入QUIT就可以了,而不必輸入pygame.locals.QUIT。
如果Event對象是一個停止事件,就會調用pygame.quit()和sys.exit()函數。pygame. quit()是pygame.init()函數的一種相反的函數,它運行的代碼會使得Pygame庫停止工作。在調用sys.exit()終止程序之前,總是應該先調用pygame.quit()。通常,由于程序退出之前,Python總是會關閉pygame,這不會真的有什么問題。但是,在IDLE中有一個bug,如果一個Pygame程序在調用pygame.quit()之前就終止了,將會導致IDLE掛起。
鍵盤按鍵
event.key==ord(‘a’)
字母a-z: ord(‘a’)----ord(‘z’), ord()內字母必須小寫,否則出錯。傳遞的是鍵盤對應小寫字母的ASCII值
event.key==K_LEFT
箭頭鍵arrow keys: K_LEFT, K_RIGHT, K_UP, K_DOWN.鍵盤右邊的四個箭頭按鍵
退出鍵ESC: K_ESCAPE
因為導入了from pygame.locals import*,所以我們可以用K_LEFT代替pygame.locals.K_LEFT
| K_LEFT | Left arrow | K_HOME | Home |
| K_RIGHT | Right arrow | K_END | End |
| K_UP | Up arrow | K_PAGEUP | PgUp |
| K_DOWN | Down arrow | K_PAGEDOWN | PgDn |
| K_ESCAPE | Esc | K_F1 | F1 |
| K_BACKSPACE | Backspace | K_F2 | F2 |
| K_TAB | Tab | K_F3 | F3 |
| K_RETURN | Return or Enter | K_F4 | F4 |
| K_SPACE | Space bar | K_F5 | F5 |
| K_DELETE | Del | K_F6 | F6 |
| K_LSHIFT | Left Shift | K_F7 | F7 |
| K_RSHIFT | Right Shift | K_F8 | F8 |
| K_LCTRL | Left Ctrl | K_F9 | F9 |
| K_RCTRL | Right Ctrl | K_F10 | F10 |
| K_LALT | Left Alt | K_F11 | F11 |
| K_RALT | Right Alt | K_F12 | F12 |
pygame.event
用于處理事件與事件隊列的 Pygame 模塊。
函數
pygame.event.pump() — 讓 Pygame 內部自動處理事件
pygame.event.get() — 從隊列中獲取事件
pygame.event.poll() — 從隊列中獲取一個事件
pygame.event.wait() — 等待并從隊列中獲取一個事件
pygame.event.peek() — 檢測某類型事件是否在隊列中
pygame.event.clear() — 從隊列中刪除所有的事件
pygame.event.event_name() — 通過 id 獲得該事件的字符串名字
pygame.event.set_blocked() — 控制哪些事件禁止進入隊列
pygame.event.set_allowed() — 控制哪些事件允許進入隊列
pygame.event.get_blocked() — 檢測某一類型的事件是否被禁止進入隊列
pygame.event.set_grab() — 控制輸入設備與其他應用程序的共享
pygame.event.get_grab() — 檢測程序是否共享輸入設備
pygame.event.post() — 放置一個新的事件到隊列中
pygame.event.Event() — 創建一個新的事件對象
pygame.event.EventType — 代表 SDL 事件的 Pygame 對象
Pygame 通過事件隊列控制所有的時間消息。該模塊中的程序將幫你管理事件隊列。輸入隊列很大程度依賴于 pygame 的 display 模塊。如果 display 沒有被初始化,顯示模式沒有被設置,那么事件隊列就還沒有開始真正工作。
常規的隊列是由 pygame.event.EventType 定義的事件對象的組成,有多種方法來訪問里邊的事件對象:從簡單的檢測事件是否存在,到直接從棧中獲取它們。
為了保持 Pygame 和系統同步,你需要調用 pygame.event.pump() 確保實時更新,你將在游戲的每次循環中調用這個函數。
在做測試時,你可以輸出事件對象以及相應的類型和成員。來自系統的事件都有一個事件類型和對應的成員屬性,下邊是每個事件類型以及對應的成員屬性列表:
pygame.event.get()
從隊列中獲取事件。
get() -> Eventlist
get(type) -> Eventlist
get(typelist) -> Eventlist
這將獲取并從隊列中刪除事件。如果指定一個或多個 type 參數,那么只獲取并刪除指定類型的事件。
請注意,如果你只從隊列中獲取和刪除指定的事件,那么久而久之,隊列可能被你不關注的事件所填滿。
pygame.font字體
1.從系統字體庫創建一個 Font 對象
font = pygame.font.SysFont(None, 48) #不熟悉字體名的就用None
pygame.font.SysFont(“字體”,字體大小)
舉例
font = pygame.font.SysFont(‘Arial’, 48)
2.使用對象里的 render方法渲染文字
render(text, antialias, color, background=None) -> Surface
舉例
textobj = font.render(“”hello“”, 1, TEXTCOLOR)
3.獲取字體矩形坐標
textrect = textobj.get_rect()
4.字體矩形坐標左上點賦值
textrect.topleft = (x, y)
5.字體更新到游戲窗口上
surface.blit(textobj, textrect)
drawText(‘Zombie VS Plants’, font, windowSurface, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 4))
image圖像
>>> pygame.image.__doc__
‘pygame module for image transfer’
>>> dir(pygame.image)
[‘__doc__’, ‘__file__’, ‘__name__’, ‘__package__’, ‘frombuffer’, ‘fromstring’, ‘get_extended’, ‘load’, ‘load_basic’, ‘load_extended’, ‘save’, ‘save_extended’, ‘tostring’]
2
圖形尺寸轉換的函數:
>>> pygame.transform.scale.__doc__
‘scale(Surface, (width, height), DestSurface = None) -> Surface\nresize to new resolution’
zombieImage=pygame.image.load(‘zombie.png’)
zombieImageStretchedImage=pygame.transform.scale(zombieImage,(40,40))
pygame.transform.scale()函數可以放大或縮小精靈。
第一個參數是pygame.Surface 對象上畫的圖像。第二個參數是圖形新尺寸。
pygame.transform.scale()函數返回一個pygame.Surface對象,此對象上的圖像被賦予新尺寸。我們把原尺寸圖像保存在變量playerImage 。但新的圖像保存在變量playerStretchedImage。
playerImage and foodImage中保存的surface對象和用于window的surface對象一樣。游戲中,我們把這些圖像,字體的surfaces復制到window的surface,這樣用戶就可以在window窗口一目了然。Font 對象render()方法產生的surface對象也一樣,為了顯示文字,我們不得不復制surface對象到window surface對象。最后通過update()方法把window surface對象顯示到屏幕上。
當矩形對象代表player的位置和尺寸時,player的圖像也被保存在 playerStretchedImage變量中。我們用 pygame.transform.scale()函數改變了圖像尺寸。確保傳遞原surface對象到變量 playerImage ,而不是到變量playerStretchedImage。圖像尺寸變化后,圖像會有點受損。如果反復變化尺寸,受損會越來越明顯。但我們把原圖像賦予新尺寸,受損只有小小一次。這就是為什么我們把playerImage變量作為第一個參數傳遞給pygame.transform.scale()
3
圖形載入的函數
pygame.image.load.__doc__
‘pygame module for image transfer’
pygame.image.load()函數被傳遞一個圖形文件的字符串參數,然后加載。 value of pygame.image.load()返回一個surface對象,這個對象中,圖像文件中圖像畫在它的surface上。我們把這surface對象保存在playerimage內。要確保圖像位置和python目錄一致。
sprite精靈代表一個二維圖像,并作為屏幕上圖形一部分。
這是精靈作為全圖的例子
精靈圖像被畫在背景頂部。注意我們可以水平翻轉精靈圖像,這樣精靈貌似朝著另一個方向。我們可以在同一個窗口畫多個相同精靈。我們也可以重新定義精靈的尺寸,變大或變小。背景圖像可以被看做一個大精靈。
精靈圖像被畫在背景頂部。注意我們可以水平翻轉精靈圖像,這樣精靈貌似朝著另一個方向。我們可以在同一個窗口畫多個相同精靈。我們也可以重新定義精靈的尺寸,變大或變小。背景圖像可以被看做一個大精靈。
精靈被保存在電腦圖像文件中pygame用的圖像格式包括: BMP, PNG, JPG (and JPEG), and GIF.你也可以從web瀏覽器下載圖像,你也可以用繪圖程序制作圖像。繪圖工具有photoshop,MS Paint or Tux Paint.
pygame.rect()
rect = pygame.Rect(300, 100, 40, 40)
Pygame 通過 Rect 對象存儲和操作矩形區域。一個 Rect 對象可以由 left,top,width,height 幾個值創建。
rect對象是用來存儲矩形對象的,rect對象有一些虛擬屬性,
比如top.left,bottom.right這些是用來固定矩形的位置的,
還有size,width,height,這些是描述矩形大小,寬高分別是多大,
center為矩形的中心點,其實就是關于橫縱坐標的二元組,因此又有centerx,centery兩個屬性。此外,還有x,y。
2.來自Pygame中文文檔的解釋:
class pygame.Rect
Rect是用于存儲矩形坐標的pygame對象。
“構造”方法:
1).rect = pygame.Rect( left , top, width, height )
2). rect = pygame.Rect(( left , top),( width, height) )
3).rect = pygame.Rect(object)
Rect.move_ip
moves the rectangle, in place
Rect.move_ip(x, y): return None
Same as the Rect.move - moves the rectangle method, but operates in place.
區別在于move_ip改變直接調整對象,move返回一個改變后的對象。
surface.blit VS pygame.display.update()
surface.blit是在游戲窗口surface上繪制對象
pygame.display.update()是把游戲窗口surface加載到電腦顯示屏幕上
Surface.blit()
windowSurface.blit(bouncerStretchedImage,rect)
做出blit這個動作的人是一個Surface類的實例,
這個人即將在自己身上畫圖,
他需要兩個參數:要畫的圖片,和畫的位置,即source和rect.
source的類型是Surface, pygame.image.load(圖片路徑)返回的就是Surface
rect需要指定兩個值,left和top,Surface類有get_rect()方法,返回Rect
Rect 是這個樣子:
Rect(left, top, width, height) -> Rect
(left,top)坐標確定圖片所在位置,width和height確定圖片寬和高
沖突檢測
圖形化游戲最常見行為就是沖突檢測。沖突檢測指:屏幕上兩個對象是否重疊。如果玩家碰到敵人,則可能損失生命值。在矩形彈動游戲中,沖突檢測指兩個矩形是否重疊。
>>> pygame.Rect.colliderect.__doc__
‘colliderect(Rect) -> bool\ntest if two rectangles overlap’
def playerHasHitZombie(playerRect, zombies):#test if two rectangles overlap測試是否觸碰到僵尸if playerRect.colliderect(z['rect']):def bulletHasHitZombie(bullets, zombies):if b['rect'].colliderect(z['rect']):bullets.remove(b)#測試子彈是否觸碰到新僵尸。如果是,就把該僵尸移除def bulletHasHitCrawler(bullets, newKindZombies):if b['rect'].colliderect(c['rect']):bullets.remove(b)創建一個簡單的游戲窗口
首先輸入import pygame,sys導入具有所有可用pygame模塊的包和系統模塊。
現在游戲窗口還沒有任何內容,之后我們可以逐步添加,設計自己的游戲。我已經用pygame完成了貪吃蛇,植物大戰僵尸,俄羅斯方塊,開心消消樂等知名游戲。
2.實例:python代碼寫個植物大戰僵尸游戲
植物大戰僵尸
《植物大戰僵尸》是由PopCap Games開發的一款益智策略類單機游戲,發售于2009年5月5日。玩家通過利用多種植,并切換不同的功能,快速有效地把僵尸阻擋在入侵的道路上。
游戲里有26種僵尸,包括鐵桶,報紙,鐵門,橄欖球頭盔,雪橇車,南瓜頭,礦工帽,鐵梯僵尸。這些僵尸會入侵我們后花園,我們要用各種植物消滅入侵僵尸。
49種植物每種都有不同的功能,例如櫻桃炸彈可以和周圍一定范圍內的所有僵尸同歸于盡,而食人花可以吃掉最靠近自己的一只僵尸。玩家可以針對不同僵尸的弱點來合理地種植植物,這也是勝利的訣竅。
下圖是我用pygame編寫的簡易版植物大戰僵尸游戲一個藍色植物正在吐出圓球攻擊僵尸,僵尸數量和移動速度可以自己控制。如果集中一個僵尸,score分數會增加一分,zombies gotten past記錄有多少僵尸已經越過植物。當然我還可以設計一些作弊的按鍵,非常有趣!
不同的敵人,不同的玩法構成五種不同的游戲模式,加之黑夜、濃霧以及泳池之類的障礙增加了游戲挑戰性。
這是房頂上植物們拼命抵抗僵尸入侵場景。
這是在后花園的游泳池里植物們拼命抵抗僵尸入侵場景。
僵尸挺聰明的,如果白天入侵不成功,就晚上搞偷襲。這是在深夜植物們拼命抵抗僵尸入侵場景。
這款python代碼當然不是復現原款游戲所有功能,而是簡單模擬一下其中樂趣。首先我們準備好以下素材。包括三張僵尸圖片:
BucketheadZombie.gif,ConeheadZombie.gif,zombie.png。
一張植物圖片plant.gif,一張背景圖片background.png,一張子彈圖片bullet.png
一首背景音樂background.mp3,一首游戲結束音樂gameover.mp3。由于游戲是之前基于python2.7版本寫的,因此建議素材名稱使用英文,python2版本對中文支持不太友好。
由于這款游戲代碼量太大,這里就不一一展開說明,我建議你們直接去下載源代碼和圖片,然后根據自己愛好,更改一下背景音樂,圖片,和僵尸數量,移動速度等參數設置。我對游戲一些重要語法做一些說明。
pygame.display.set_caption(words)設置窗口標題
pygame.display.set_caption(words)方法是設置窗口標題,words參數是窗口標題。我們沿用之前腳本運行下面腳本,我們就生成了一個有Zombie VS Plants標題的窗口。
pygame.event事件
常見事件有QUIT,KEYDOWN,KEYUP
while True: #main game loop游戲主循環for event in pygame.event.get(): #遍歷pygame事件列表if event.type==QUIT: #如果點擊關閉按鈕(window右上)pygame.quit() #關閉pygame庫sys.exit() #系統退出建立一個簡單游戲窗口
import pygame,sys #導入pygame和sys模塊from pygame.locals import* #導入pygame 局部變量pygame.init() #pygame所有模塊初始化screen=pygame.display.set_mode((400,300))#設置屏幕長和寬值pygame.display.set_caption('Zombie VS Plants')# 設置窗口標題while True: #main game loop游戲主循環for event in pygame.event.get(): #遍歷pygame事件列表if event.type==QUIT: #如果點擊關閉按鈕(window右上)pygame.quit() #關閉pygame庫sys.exit() #系統退出pygame.time.Clock
pygame.time.Clock創建一個新的Clock對象,該對象可用于跟蹤時間量。 時鐘還提供了多種功能來幫助控制游戲的幀頻。
pygame中的時間以毫秒(1/1000秒)表示。 大多數平臺的時間分辨率有限,大約為10毫秒。 該分辨率(以毫秒為單位)在TIMER_RESOLUTION常量中給出。
pygame.time.Clock.tick()
tick(framerate=0) -> milliseconds
每幀應調用一次此方法。 它將計算自上次調用以來經過了多少毫秒。
如果您傳遞可選的幀速率參數,該功能將延遲以使游戲的運行速度低于給定的每秒滴答聲。 這可以用來幫助限制游戲的運行速度。 通過每幀調用Clock.tick(40)一次,該程序將永遠不會以每秒40幀以上的速度運行。一般情況framerate設置為40.
游戲運行時每秒所運行的幀數(簡稱FPS,Frames Per Second) 和視頻一樣,FPS越大,在屏幕上的視頻就越來越平滑,直到一個臨界點(大約是100FPS),超過這個臨界點,再高的FPS都只是一個令人驚奇的數值,400FPS和100FPS在人的視覺中幾乎沒有差別。
FPS取決于顯卡,其次是內存,CPU,然后是網絡(如果是網絡游戲的話)與硬盤。
一般游戲都是40左右fps就可以稱之為流暢了。比如策略類(三國志什么的)5fps也是可以接受的。但賽車類 5fps根本玩不下去。
每款游戲都會有一個官方提供的最低配置要求,尤其是網絡游戲,但這個最低配置僅僅適用于將游戲內的所有視頻效果全部關閉的狀態下使用,而且網絡游戲中對于網速的問題是忽略不計的。
只有提高電腦的顯卡、內存才能在網絡因素不確定的情況下達到最理想的游戲流暢效果。
- 音樂music
我們曾經玩任何游戲都會伴隨動聽的背景音樂。pygame.mixer是一個用來處理聲音的模塊,其含義為“混音器”。因此我們準備用以下方法pygame.mixer.music.load(‘background.mp3’)加載mp3格式背景音樂并準備播放。這樣游戲就會深動形象。
pygame.mixer.music.play(loop, start)方法用于播方音樂,loop表示循環次數,如果loop=1表示音樂播方一次。如果loop=2, 表示音樂播方兩次。如果loop=-1,表示音樂不停循環。start 參數控制音樂從哪里開始播放。開始的位置取決于音樂的格式。MP3 和 OGG 使用時間表示播放位置(以秒為單位)。MOD使用模式順序編號表示播放位置。如果音樂文件無法設置開始位置,則傳遞了start參數后會產生一個NotImplementedError 錯誤。
pygame.mixer.music.stop()方法用于結束音樂播放。如果游戲結束,我們可以加上這句方法,停止播放音樂。
pygame.mixer.music.load('background.mp3') ##載入一個音樂文件用于播放#,如果 loops = -1,則表示無限重復播放。start 參數控制音樂從哪里開始播放。pygame.mixer.music.play(-1, 0.0) #開始播放音樂流pygame.mixer.music.stop()#停止音樂播放我們把加載和播方聲音的代碼加入主程序,這樣游戲窗口就有音樂了。
import pygame,sys #導入pygame和sys模塊from pygame.locals import* #導入pygame 局部變量pygame.init() #pygame所有模塊初始化screen=pygame.display.set_mode((400,300))#設置屏幕長和寬值pygame.display.set_caption('Zombie VS Plants')pygame.mixer.music.load('background.mp3') ##載入一個音樂文件用于播放#,如果 loops = -1,則表示無限重復播放。start 參數控制音樂從哪里開始播放。pygame.mixer.music.play(-1, 0.0) #開始播放音樂流while True: #main game loop游戲主循環for event in pygame.event.get(): #遍歷pygame事件列表if event.type==QUIT: #如果點擊關閉按鈕(window右上)pygame.quit() #關閉pygame庫sys.exit() #系統退出pygame.mixer.music.stop()#停止音樂播放游戲結束時也會有相應音樂,我們文件里游戲結束音樂時wav格式的,和之前mp3格式不一樣,我們用gameOverSound = pygame.mixer.Sound(‘gameover.wav’)方法把游戲結束音樂放入gameOverSound變量。gameOverSound.play()方法播放游戲結束音樂。gameOverSound.stop()方法用于停止游戲結束聲音播放。
gameOverSound = pygame.mixer.Sound('gameover.wav')gameOverSound.play() #播放游戲結束時聲音gameOverSound.stop() #游戲結束聲音停止- 參數前置
我們用pygame.display.set_mode((400,300))方法設置屏幕大小時候400,300為屏幕的長和寬。在大型程序設計時,一般不把具體數字放入方法里,而是用變量代替。我們用WINDOWWIDTH表示游戲窗口寬度,用WINDOWHEIGHT 表示游戲窗口高度,WINDOWWIDTH = 1024,WINDOWHEIGHT = 600。我們用以下代碼實現游戲窗口大小的參數前置。
import pygame,sys #導入pygame和sys模塊from pygame.locals import* #導入pygame 局部變量WINDOWWIDTH = 1024 #游戲窗口寬度WINDOWHEIGHT = 600 #游戲窗口高度pygame.init() #pygame所有模塊初始化screen=pygame.display.set_mode((400,300))#設置屏幕長和寬值pygame.display.set_caption('Zombie VS Plants')windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))pygame.mixer.music.load('background.mp3') ##載入一個音樂文件用于播放#,如果 loops = -1,則表示無限重復播放。start 參數控制音樂從哪里開始播放。pygame.mixer.music.play(-1, 0.0) #開始播放音樂流while True: #main game loop游戲主循環for event in pygame.event.get(): #遍歷pygame事件列表if event.type==QUIT: #如果點擊關閉按鈕(window右上)pygame.mixer.music.stop()#停止播放音樂pygame.quit() #關閉pygame庫sys.exit() #系統退出如果我們想要讓游戲窗口在顯示器上全屏展示,我們用pygame.FULLSCREEN對象。
import pygame,sys #導入pygame和sys模塊from pygame.locals import* #導入pygame 局部變量WINDOWWIDTH = 1024 #游戲窗口寬度WINDOWHEIGHT = 600 #游戲窗口高度pygame.init() #pygame所有模塊初始化screen=pygame.display.set_mode((400,300))#設置屏幕長和寬值pygame.display.set_caption('Zombie VS Plants')windowSurface=pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT),pygame.FULLSCREEN)pygame.mixer.music.load('background.mp3') ##載入一個音樂文件用于播放#,如果 loops = -1,則表示無限重復播放。start 參數控制音樂從哪里開始播放。pygame.mixer.music.play(-1, 0.0) #開始播放音樂流while True: #main game loop游戲主循環for event in pygame.event.get(): #遍歷pygame事件列表if event.type==QUIT: #如果點擊關閉按鈕(window右上)pygame.mixer.music.stop() #停止播放音樂pygame.quit() #關閉pygame庫sys.exit() #系統退出- 鼠標
#鼠標設置不可見
pygame.mouse.set_visible(False)
- 鍵盤設置
#Python菜鳥快樂游戲編程_pygame:https://ke.qq.com/course/3065512for event in pygame.event.get():if event.type==QUIT:if event.type==pygame.locals.KEYDOWN:#change the keyboard variables鍵盤鍵設置上下左右if event.key==pygame.locals.K_LEFT or event.key==ord('a'):moveRight=FalsemoveLeft=Trueif event.key==pygame.locals.K_RIGHT or event.key==ord('d'):moveLeft=FalsemoveRight=Trueif event.key==pygame.locals.K_UP or event.key==ord('w'):moveDown=FalsemoveUp=Trueif event.key==pygame.locals.K_DOWN or event.key==ord('s'):moveDown=TruemoveUp=False#有KEYDOWN就一定有KEYUP,否則游戲對象會持續移動if event.type==pygame.locals.KEYUP:if event.key==pygame.locals.K_ESCAPE:pygame.quit()sys.exit()if event.key==pygame.locals.K_LEFT or event.key==ord('a'):moveLeft=Falseif event.key==K_RIGHT or event.key==ord('d'):moveRight=Falseif event.key==K_UP or event.key==ord('w'):moveUp=Falseif event.key==K_DOWN or event.key==ord('s'):moveDown=False# move the bouncer data structureif moveDown and p_destination.bottom<WINDOWHEIGHT:p_destination.top+=PLAYERMOVERATEif moveUp and p_destination.top>0:p_destination.top-=PLAYERMOVERATEif moveLeft and p_destination.left>0:p_destination.left-=PLAYERMOVERATEif moveRight and p_destination.right<WINDOWWIDTH:p_destination.right+=PLAYERMOVERATE# Draw the game world on the window.windowSurface.blit(rescaledBackground, (0, 0))windowSurface.blit(zombieStretchedImage,z_destination)windowSurface.blit(playerImage,p_destination)
- 發射子彈代碼
- random.randint(a,b)隨機生成若干移動僵尸
在python中的random.randint(a,b)用于生成一bai個指定范圍內的整數。du其中參數zhia是下限,參數b是上限,生成的隨機dao數n: a <= n <= b。
import pygame, random, sys, timefrom pygame.locals import *#連續發射兩個子彈的距離,值越小,子彈距離越近,反之亦然ZOMBIESIZE = 100 #includes newKindZombiesADDNEWKINDZOMBIE = ADDNEWZOMBIERATENEWKINDZOMBIESPEED = NORMALZOMBIESPEED / 2# set up the colors顏色值設置,可用于背景顏色# set up pygame, the window, and the mouse cursor#reate an object to help track timemainClock = pygame.time.Clock()windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))#, pygame.FULLSCREEN)pygame.display.set_caption('Zombie Defence')#pygame.mouse.set_visible(False)font = pygame.font.SysFont(None, 48)pygame.mixer.music.load('grasswalk.mp3')playerImage = pygame.image.load('SnowPea.gif')#get the rectangular area of the Surface#Returns a new rectangle covering the entire surface. This rectangle will#always start at (0, 0) with a width and height the same size as the image.playerRect = playerImage.get_rect()bulletImage = pygame.image.load('SnowPeashooterBullet.gif')bulletRect = bulletImage.get_rect()zombieImage=pygame.image.load("zombie.png")zombieStretchedImage=pygame.transform.scale(zombieImage,(80,80))z_destination=pygame.Rect(944, 300, 80, 80)backgroundImage = pygame.image.load('background.png')#對背景圖片尺寸重新調整大小,寬為WINDOWWIDTH,長為WINDOWHEIGHTrescaledBackground = pygame.transform.scale(backgroundImage, (WINDOWWIDTH, WINDOWHEIGHT))playerRect.topleft = (50, WINDOWHEIGHT /2)moveLeft = moveRight = Falsepygame.mixer.music.play(-1, 0.0)while True: # the game loop runs while the game part is playingfor event in pygame.event.get():if event.type == QUIT:if event.type == KEYDOWN:if event.key == K_UP or event.key == ord('w'):moveDown = FalsemoveUp = Trueif event.key == K_DOWN or event.key == ord('s'):moveUp = FalsemoveDown = Trueif event.key == K_SPACE:shoot = Trueif event.type == KEYUP:if event.key == K_ESCAPE:terminate()if event.key == K_UP or event.key == ord('w'):moveUp = Falseif event.key == K_DOWN or event.key == ord('s'):moveDown = Falseif event.key == K_SPACE:shoot = False# Add new zombies at the top of the screen, if needed.增加上市zombieAddCounter += 1if zombieAddCounter == ADDNEWKINDZOMBIE:zombieAddCounter = 0zombieSize = ZOMBIESIZE newZombie = {'rect': pygame.Rect(WINDOWWIDTH, random.randint(10,WINDOWHEIGHT-zombieSize-10), zombieSize, zombieSize),'surface':pygame.transform.scale(zombieImage, (zombieSize, zombieSize)),}zombies.append(newZombie)bulletAddCounter += 1print("bulletAddCounter:",bulletAddCounter)#當while循環次數大于ADDNEWBULLETRATE時,才能發射子彈if bulletAddCounter >= ADDNEWBULLETRATE and shoot == True:#if shoot == True: #如果不限制,子彈會連發,沒有距離感bulletAddCounter = 0#playerRect.centery-25是為了讓子彈上升一點,與植物炮口平行,centerx+10是為了子彈在前面點出現newBullet = {'rect':pygame.Rect(playerRect.centerx+10, playerRect.centery-30, bulletRect.width, bulletRect.height),'surface':pygame.transform.scale(bulletImage, (bulletRect.width, bulletRect.height)),}bullets.append(newBullet)# Move the player around.if moveUp and playerRect.top > 30:playerRect.move_ip(0,-1 * PLAYERMOVERATE)if moveDown and playerRect.bottom < WINDOWHEIGHT-10:playerRect.move_ip(0,PLAYERMOVERATE)# move the bullet移動子彈b['rect'].move_ip(1 * BULLETSPEED, 0)#print(b['rect'])z['rect'].move_ip(-1*NORMALZOMBIESPEED, 0)# Draw the game world on the window.windowSurface.blit(rescaledBackground, (0, 0))# Draw the player's rectangle, railswindowSurface.blit(playerImage, playerRect)windowSurface.blit(zombieStretchedImage,z_destination)# draw each bullet將所有子彈繪制到游戲界面上windowSurface.blit(b['surface'], b['rect'])windowSurface.blit(z['surface'], z['rect'])pygame.display.update()#tick(framerate=0) -> milliseconds#幀速率參數,該功能將延遲以使游戲的運行速度低#print("bullets",bullets)完整的植物大戰僵尸游戲代碼如下。你們可以根據自己偏好來改變人物圖片,背景,配音。
import pygame, random, sys, timefrom pygame.locals import *ZOMBIESIZE = 100 #includes newKindZombiesADDNEWKINDZOMBIE = ADDNEWZOMBIERATENEWKINDZOMBIESPEED = NORMALZOMBIESPEED / 2TEXTCOLOR = (255, 255, 255)def waitForPlayerToPressKey():for event in pygame.event.get():if event.type == QUIT:terminate()if event.type == KEYDOWN:if event.key == K_ESCAPE: # pressing escape quitsterminate()if event.key == K_RETURN:returndef playerHasHitZombie(playerRect, zombies):#test if two rectangles overlap測試是否觸碰到僵尸if playerRect.colliderect(z['rect']):def bulletHasHitZombie(bullets, zombies):if b['rect'].colliderect(z['rect']):bullets.remove(b)#測試子彈是否觸碰到新僵尸。如果是,就把該僵尸移除def bulletHasHitCrawler(bullets, newKindZombies):if b['rect'].colliderect(c['rect']):bullets.remove(b)def drawText(text, font, surface, x, y):textobj = font.render(text, 1, TEXTCOLOR)textrect = textobj.get_rect()textrect.topleft = (x, y)#draw one image onto anothersurface.blit(textobj, textrect)# set up pygame, the window, and the mouse cursor#reate an object to help track timemainClock = pygame.time.Clock()windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))#, pygame.FULLSCREEN)pygame.display.set_caption('Zombie VS Plants')pygame.mouse.set_visible(False)font = pygame.font.SysFont(None, 48)gameOverSound = pygame.mixer.Sound('gameover.wav')pygame.mixer.music.load('background.mp3')playerImage = pygame.image.load('plant.gif')#get the rectangular area of the Surface#Returns a new rectangle covering the entire surface. This rectangle will#always start at (0, 0) with a width and height the same size as the image.playerRect = playerImage.get_rect()bulletImage = pygame.image.load('bullet.gif')bulletRect = bulletImage.get_rect()zombieImage = pygame.image.load('zombie.png')newKindZombieImage = pygame.image.load('ConeheadZombie.gif')#newKindZombieImage = pygame.image.load('trump31.png')backgroundImage = pygame.image.load('background.png')#對背景圖片尺寸重新調整大小,寬為WINDOWWIDTH,長為WINDOWHEIGHTrescaledBackground = pygame.transform.scale(backgroundImage, (WINDOWWIDTH, WINDOWHEIGHT))# show the "Start" screenwindowSurface.blit(rescaledBackground, (0, 0))windowSurface.blit(playerImage, (WINDOWWIDTH / 2, WINDOWHEIGHT - 70))drawText('Zombie VS Plants', font, windowSurface, (WINDOWWIDTH / 4), (WINDOWHEIGHT / 4))drawText('Press Enter to start', font, windowSurface, (WINDOWWIDTH / 3) - 10, (WINDOWHEIGHT / 3) + 50)waitForPlayerToPressKey()# set up the start of the gamezombiesGottenPast = 0playerRect.topleft = (50, WINDOWHEIGHT /2)moveLeft = moveRight = FalsemoveUp=moveDown = FalsenewKindZombieAddCounter = 0bulletAddCounter = 40pygame.mixer.music.play(-1, 0.0)while True: # the game loop runs while the game part is playingfor event in pygame.event.get():if event.type == QUIT:terminate()if event.type == KEYDOWN:if event.key == K_UP or event.key == ord('w'):moveDown = FalsemoveUp = Trueif event.key == K_DOWN or event.key == ord('s'):moveUp = FalsemoveDown = Trueif event.key == K_SPACE:shoot = Trueif event.type == KEYUP:if event.key == K_ESCAPE:terminate()if event.key == K_UP or event.key == ord('w'):moveUp = Falseif event.key == K_DOWN or event.key == ord('s'):moveDown = Falseif event.key == K_SPACE:shoot = False# Add new zombies at the top of the screen, if needed.增加上市zombieAddCounter += 1if zombieAddCounter == ADDNEWKINDZOMBIE:zombieAddCounter = 0zombieSize = ZOMBIESIZE newZombie = {'rect': pygame.Rect(WINDOWWIDTH, random.randint(10,WINDOWHEIGHT-zombieSize-10), zombieSize, zombieSize),'surface':pygame.transform.scale(zombieImage, (zombieSize, zombieSize)),}zombies.append(newZombie)# Add new newKindZombies at the top of the screen, if needed.newKindZombieAddCounter += 1if newKindZombieAddCounter == ADDNEWZOMBIERATE:newKindZombieAddCounter = 0newKindZombiesize = ZOMBIESIZEnewCrawler = {'rect': pygame.Rect(WINDOWWIDTH, random.randint(10,WINDOWHEIGHT-newKindZombiesize-10), newKindZombiesize, newKindZombiesize),'surface':pygame.transform.scale(newKindZombieImage, (newKindZombiesize, newKindZombiesize)),}newKindZombies.append(newCrawler)bulletAddCounter += 1if bulletAddCounter >= ADDNEWBULLETRATE and shoot == True:bulletAddCounter = 0newBullet = {'rect':pygame.Rect(playerRect.centerx+10, playerRect.centery-25, bulletRect.width, bulletRect.height),'surface':pygame.transform.scale(bulletImage, (bulletRect.width, bulletRect.height)),}bullets.append(newBullet)# Move the player around.if moveUp and playerRect.top > 30:playerRect.move_ip(0,-1 * PLAYERMOVERATE)if moveDown and playerRect.bottom < WINDOWHEIGHT-10:playerRect.move_ip(0,PLAYERMOVERATE)# Move the zombies down.for z in zombies:z['rect'].move_ip(-1*NORMALZOMBIESPEED, 0)# Move the newKindZombies down.for c in newKindZombies:c['rect'].move_ip(-1*NEWKINDZOMBIESPEED,0)# move the bulletfor b in bullets:b['rect'].move_ip(1 * BULLETSPEED, 0)# Delete zombies that have fallen past the bottom.for z in zombies[:]:if z['rect'].left < 0:zombies.remove(z)zombiesGottenPast += 1# Delete newKindZombies that have fallen past the bottom.for c in newKindZombies[:]:if c['rect'].left <0:newKindZombies.remove(c)zombiesGottenPast += 1for b in bullets[:]:if b['rect'].right>WINDOWWIDTH:bullets.remove(b)# check if the bullet has hit the zombie 檢查子彈是否觸碰到僵尸for z in zombies:if bulletHasHitZombie(bullets, zombies):score += 1zombies.remove(z)for c in newKindZombies:if bulletHasHitCrawler(bullets, newKindZombies):score += 1newKindZombies.remove(c) # Draw the game world on the window.windowSurface.blit(rescaledBackground, (0, 0))# Draw the player's rectangle, railswindowSurface.blit(playerImage, playerRect)# Draw each baddiefor z in zombies:windowSurface.blit(z['surface'], z['rect'])for c in newKindZombies:windowSurface.blit(c['surface'], c['rect'])# draw each bulletfor b in bullets:windowSurface.blit(b['surface'], b['rect'])# Draw the score and how many zombies got pastdrawText('zombies gotten past: %s' % (zombiesGottenPast), font, windowSurface, 10, 20)drawText('score: %s' % (score), font, windowSurface, 10, 50)# update the displaypygame.display.update()# Check if any of the zombies has hit the player.if playerHasHitZombie(playerRect, zombies):if playerHasHitZombie(playerRect, newKindZombies):# check if score is over MAXGOTTENPASS which means game overif zombiesGottenPast >= MAXGOTTENPASS:#tick(framerate=0) -> milliseconds#幀速率參數,該功能將延遲以使游戲的運行速度低mainClock.tick(FPS)# Stop the game and show the "Game Over" screen.游戲結束執行命令pygame.mixer.music.stop()gameOverSound.play() #播放游戲結束時聲音if zombiesGottenPast >= MAXGOTTENPASS:windowSurface.blit(rescaledBackground, (0, 0))windowSurface.blit(playerImage, (WINDOWWIDTH / 2, WINDOWHEIGHT - 70))drawText('score: %s' % (score), font, windowSurface, 10, 30)drawText('GAME OVER', font, windowSurface, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 3))drawText('YOUR COUNTRY HAS BEEN DESTROIED', font, windowSurface, (WINDOWWIDTH / 4)- 80, (WINDOWHEIGHT / 3) + 100)drawText('Press enter to play again or escape to exit', font, windowSurface, (WINDOWWIDTH / 4) - 80, (WINDOWHEIGHT / 3) + 150)pygame.display.update()waitForPlayerToPressKey()if playerHasHitZombie(playerRect, zombies):windowSurface.blit(rescaledBackground, (0, 0))windowSurface.blit(playerImage, (WINDOWWIDTH / 2, WINDOWHEIGHT - 70))drawText('score: %s' % (score), font, windowSurface, 10, 30)drawText('GAME OVER', font, windowSurface, (WINDOWWIDTH / 3), (WINDOWHEIGHT / 3))drawText('YOU HAVE BEEN KISSED BY THE ZOMMBIE', font, windowSurface, (WINDOWWIDTH / 4) - 80, (WINDOWHEIGHT / 3) +100)drawText('Press enter to play again or escape to exit', font, windowSurface, (WINDOWWIDTH / 4) - 80, (WINDOWHEIGHT / 3) + 150)pygame.display.update()waitForPlayerToPressKey()gameOverSound.stop() #游戲結束聲音停止這一章我們學習了python的pygame模塊,了解了pygame模塊的基礎知識和如何編寫植物大戰僵尸的DIY游戲。總之pygame在編寫視頻游戲上方便,高效,且具有高度的可移植性,幾乎可以在所有平臺和操作系統上運行。不要等了,趕緊去安裝pygame模塊,開始第一個游戲編程之旅吧。
論文涉及機器學習建模解決方案
版權聲明:文章來自公眾號(python風控模型),未經許可,不得抄襲。遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
總結
以上是生活随笔為你收集整理的Python游戏编程_植物大战讲僵尸_贪吃蛇的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于达梦监视器dmmonitor的一些知
- 下一篇: springboot宿舍管理系统