激情六月丁香婷婷|亚洲色图AV二区|丝袜AV日韩AV|久草视频在线分类|伊人九九精品视频|国产精品一级电影|久草视频在线99|在线看的av网址|伊人99精品无码|午夜无码视频在线

python微信小游戲開發(fā)(從零開發(fā)一個小游戲:PyGame入門)

發(fā)布時間:2023-11-27 11:12:42 瀏覽量:165次

?從零開發(fā)一個小游戲:PyGame入門

python微信小游戲開發(fā)(從零開發(fā)一個小游戲:PyGame入門)

編程派微信號:codingpy

編程派堅信,這個時代人人都學點編程,不論對自身成長還是日常工作,都將有巨大益處。因此,選擇了通過本公號與大家分享最易學的編程語言 Python 的教程和資源,希望對你有幫助。

今天分享的是 Python 翻譯組 最新譯文,原文來自real python,是一篇比較詳細的 PyGame 游戲開發(fā)入門指南。

譯者:haiyuqiao,華中科技大學(在讀研究生),正在使用 Python 做數(shù)據(jù)分析。Fighting from now!校對:EarlGrey,編程派主頁君。

以下是正文,一起來學習吧。

PyGame是 SDL 庫的 Python 包裝器(wrapper)。SDL 是一個跨平臺庫,支持訪問計算機多媒體硬件(聲音、視頻、輸入等)。SDL 非常強大,但美中不足的是,它是基于 C 語言的,而 C 語言比較難懂,因此我們采用 PyGame 。

在本教程中,我們將介紹 PyGame 的基本邏輯和沖突檢測,以及如何在屏幕上繪圖和將外部文件導入到游戲中。

準備工作

打開PyGame下載頁面,根據(jù)你的操作系統(tǒng)和 Python 版本下載合適的 PyGame 安裝包。如果你使用的是 Python 3,那么請下載 1.9.2 版.

新建一個 .py 文件,然后輸入以下代碼:

與其他 Python 程序一樣,我們首先導入想要使用的模塊。這里,我們將導入 pygamepygame.locals ,后續(xù)我們將使用其中的一些常量。最后一行會初始化所有導入的 PyGame 模塊,在做其他操作之前必須執(zhí)行調(diào)用該函數(shù)。

基礎對象

屏幕對象

首先,我們需要一張畫布,我們稱之為“屏幕”,它是我們繪畫的平臺。為了創(chuàng)建一個屏幕,我們需要調(diào)用pygame.display 中的 set_mode 方法,然后向 set_mode() 傳遞包含屏幕窗口寬度和高度的元組(本教程中使用 800x600 尺寸)。

screen = pygame.display.set_mode((800,600))

運行上述代碼,將會彈出一個窗口,然后當程序退出后又立即消失。一點都不酷嘛,對吧?下一節(jié),我們將介紹游戲的主循環(huán),它將確保只有在我們給它正確的輸入時程序才會退出。

游戲主循環(huán)

游戲主循環(huán)/事件循環(huán)是所有操作發(fā)生的地方。在游戲過程中,它不斷的更新游戲狀態(tài),渲染游戲畫面和收集輸入指令。創(chuàng)建循環(huán)時,需要確保我們有辦法跳出循環(huán),退出應用。為此,我們將同時介紹一些基本的用戶輸入指令。所有的用戶輸入(和我們稍稍后提到的其他事件)都會進入 PyGame 的事件隊列,通過調(diào)用 pygame.event.get() 可以訪問該隊列。這將返回一個包含隊列里所有事件的列表,我們將循環(huán)這個列表,并根針對相應的事件類型做出反應?,F(xiàn)在我們只關心 KEYDOWNQUIT 事件:

將上述代碼添加到之前的代碼下,并運行。你應該看到一個空的窗口。只有你按下 ESC 鍵 或者觸發(fā)一個 QUIT 事,否則這個窗口不會消失。

Surface 和 Rects

SurfaceRects是 PyGame 中的基本構(gòu)件??梢詫?Surface 看作一張白紙,你可以在上面隨意繪畫。我們的屏幕對象也是一個 Surface 。它們可以包含圖片。Rects 是 Surface 中矩形區(qū)域的表示。

讓我們創(chuàng)建一個 50x50 像素的 Surface,然后給它涂色。由于屏幕是黑色的,所以我們使用白色。 我們?nèi)缓笳{(diào)用 get_rect() 在 Surface上 得到一個矩形區(qū)域和 Surface 的 x 軸 和 y 軸。

Blit 和 Flip

僅僅只是創(chuàng)建了 Surface 并不能在屏幕上看到它。為此我們需要將這個 Surface 繪制(Blit)到另一個 Surface 上。Blit 是一個專業(yè)術語,意思就是繪圖。你僅僅只能從一個Surface Blit 到另一個Surface,我們的屏幕就是一個 Surface 對象。以下是我們?nèi)绾螌?surf 畫到屏幕上:

# 這一行表示:將surf畫到屏幕 x:400.y:300的坐標上

screen.blit(surf,(400,300))pygame.display.flip()

blit() 有兩個參數(shù):要畫的 Surface 和 在源 Surface 上的坐標。此處我們使用屏幕的中心,但是當你運行代碼時,你會發(fā)現(xiàn)我們的 surf 并沒有出現(xiàn)在屏幕的中心。這是因為 blit() 是從左上角開始畫 surf 。

注意在 blit 之后的 pygame.display.filp() 的調(diào)用。Flip將會更新自上次 flip 后的整個屏幕,兩次 flip 之間發(fā)生的修改都將在屏幕上顯示。沒有調(diào)用flip()那就什么也不會出現(xiàn)。

Sprites

什么是 Sprites ?從編程術語來講,Sprites 是屏幕上事物的二維表達。本質(zhì)上來講,Sprite 就是一個圖片。Pygame 提供一個叫做 Sprites 的基礎類,它就是用來擴展的,可以包含想要在屏幕上呈現(xiàn)的對象一個或多個圖形表示。我們將會擴展Sprite 類,這樣可以使用它的內(nèi)建方法。我們稱這個新的對象為 PlayerPlyaer 將擴展 Sprite,現(xiàn)在只有兩個屬性:surfrect。我們也會給 surf 涂色(本教程使用白色),如之前 surface 例子,只是現(xiàn)在 Surface 屬于 Player :

現(xiàn)在我們將上述代碼整合在一起:

運行上述代碼,你將會在屏幕中心看到一個白色的矩形:

如果將 screen.blit(player.surf,(400,300)) 改成 screen.blit(player.surf,player.rect) ,你覺得會發(fā)生什么?修改之后,試著在控制臺中打印 player.rectrect 的前兩個屬性分別是 rect 左上角的 x 和 y 軸坐標。當你將 rect 傳遞給 blit ,它將會根據(jù)這個坐標畫 surface 。我們后續(xù)將使用它控制 player 移動。

用戶輸入

現(xiàn)在開始才是有趣的部分。我們要把 Player 變得可控制!之前我們提過,按鍵事件 pygame.event.get() 將把最新的事件從事件堆(event stack)中移除。Pygame 還有另外一個事件方法,pygame.event.get_pressed()。get_pressed()方法返回一個隊列,其中包含了所有按鍵事件組成的字典,我們將把它放在主循環(huán)中,這樣我們將在每一幀上的按鍵。

pressed_keys = pygame.event.get_presssed()

現(xiàn)在我們將寫一個方法,接收上面那個字典,并且根據(jù)按下的鍵定義 sprite 的行為,代碼如下:

K_UP、K_DOWN、K_LEFTK_RIGHT 對應鍵盤上的上、下、左 右方向鍵。我們判斷這些鍵是否按下,如果它為真,那么我們就朝相應的方向移動 rect()。Rects 有兩個內(nèi)建的移動方法,此處我們使用 move in place move_ip() ,因為我們希望移動 rect 并且不用復制它。

將上述方法添加到 Player 類,將 get_pressed() 調(diào)用放在主循環(huán)中。整體代碼現(xiàn)在應該是這樣的:

現(xiàn)在你可以使用方向鍵移動矩陣塊了。也許你注意到了,你可以將矩形塊移出屏幕,這可能并不是你想要的。所以我們我們需要往 update 方法中添加一些邏輯,檢測矩形的坐標是否移出了 800x600 的屏幕邊界;如果出了邊界,那么就將它放回在邊界上:

上述代碼沒有使用 move 方法,我們只要修改 上下左右的相應坐標即可。

現(xiàn)在我們添加一些敵人!

首先我們創(chuàng)建一個新的 sprite 類,命名為 Enemy。依照創(chuàng)建 player 的格式創(chuàng)建:

以上有幾點需要說明。首先,當我們在 surface 上調(diào)用 get_rect 時,我們將核心屬性 x 設為 820 ,y 的坐標為一個隨機數(shù),由 random.randint() 生成。

在最終的代碼中,我們會在文件的開頭導入 Random 庫(import random)。為什么選擇隨機數(shù)?因為我們希望敵人從屏幕右邊(820)的隨機位置(0-600)上出現(xiàn)。 我們還將使用 random 設置敵人的速度屬性,這樣敵人就會有快有慢。

敵人的 update() 方法沒有參數(shù)限制(我們不關心敵人的輸入),只要讓它向著屏幕左邊以一定的速度移動就可以了。update 方法中的最后一個 if 語句檢測敵人右側(cè)是否通過了屏幕左邊邊界(要確保它們不會一碰到屏幕的邊界就消失)。當他們通過屏幕的邊界后,我們調(diào)用 Sprite 的內(nèi)建方法 kill(),從 sprite 組中刪除它們,這樣它們就不會再被渲染出來。kill 不會釋放被它們占用的內(nèi)存, 需要你確保你不再引用它們,以便 Python 的垃圾回收器回收。

Groups

Pygame 提供的另一個很有用的對象是 Sprite 的 Groups。誠如其名,是 Sprite 的集合。為什么我們要使用 sprite.Group 而不是列表呢? 因為 sprite.Group 有一些內(nèi)建的方法,有助于解決沖突和更新問題。那現(xiàn)在就創(chuàng)建一個 Group,用來包含游戲中的所有 Sprites 。創(chuàng)建完 Group 后,我們要將 Player 添加到里面,因為它是我們目前唯一的 Sprite 。我們也可以為敵人創(chuàng)建一個 group 。 當我們調(diào)用 Sprite 的 kill() 方法時,sprite 將會從其所在的全部 group 中刪除。

python微信小游戲開發(fā)(從零開發(fā)一個小游戲:PyGame入門)

enemies = pygame.sprite.Group()

all_sprites = pygame.sprite.Group()

all_sprites.add(player)

現(xiàn)在有了 all_sprites 的 group ,我們接著改變對象渲染方式,只要渲染 group 中的所有對象即可:

現(xiàn)在,任何放到 all_sprites 中的對象都會被渲染出來。

自定義事件

現(xiàn)在我們?yōu)閿橙藙?chuàng)建了一個 sprite.Group ,但是并沒有實際的敵人。那怎樣才能在屏幕上出現(xiàn)敵人呢?我們當然可以在剛開始的時候創(chuàng)建一堆的敵人,但是這樣游戲玩不了幾秒。為此,我們創(chuàng)建一個自定義事件,它隔幾秒鐘就會觸發(fā)創(chuàng)建一批敵人。我們要監(jiān)聽該事件,方式和監(jiān)聽按鍵或退出事件一樣。創(chuàng)建自定義事件十分容易,只要命名即可:

ADDENEMY = pygame.USEREVENT +1

這樣就可以了!現(xiàn)在,我們有了一個叫做 ADDENEMY的事件,可以在主程序中監(jiān)聽它。這里我們只需要注意一點,即自定義事件需要有一個獨特的值,要比 USEREVENT 的值大,這就是我們?yōu)槭裁丛O定它為 USEREVENT + 1。這里說明一點:自定義事件本質(zhì)上就是整數(shù)常量。又因為比 USEREVENT 小的數(shù)值已經(jīng)被內(nèi)置函數(shù)占據(jù),所以創(chuàng)建的任何自定義事件都要比 USEREVENT大。

定義好事件之后,我們需要將它插入事件隊列中。因為整個游戲過程中都要創(chuàng)建它們,所以將設置一個計時器??梢酝ㄟ^ PyGame 的 time() 對象實現(xiàn)。

pygame.time.set_timer(ADDENEMY,250)

這行代碼告訴 PyGame 每隔 250 毫秒(四分之一秒) 觸發(fā)一次 ADDENEMY 事件。這是在主游戲循環(huán)之外執(zhí)行的,不過在整個游戲中都處于執(zhí)行狀態(tài)?,F(xiàn)在我們添加一些監(jiān)聽事件的代碼:

現(xiàn)在我們會監(jiān)聽ADDENEMY事件,當它觸發(fā)時,將創(chuàng)建一個 Enemy類的實例。然后我們將實例添加到enemies 這個 Sprite Group(后續(xù)用它來檢測沖突)和 all_sprites Group(這樣它會和其他對象一起渲染)。

沖突

這才是 PyGame 的魅力所在!寫沖突代碼(collision code)很難,但是 PyGame 提供了很多沖突檢測方法,你可以在這里查看其中一部分。本次教程使用 spritecollideany。spritecollideany() 接受一個 Sprite 對象和一個 Sprite.Group ,檢測 Sprite 對象是否和 Sprite Group 中的其他 Sprites 沖突。這樣,我們可以拿 Player 和敵人所在的 Sprite Group 對比,檢測 player 是否被敵人擊中。代碼實現(xiàn)如下:

檢測 player 是否 enemies 中的 Sprites 沖突,如果發(fā)生沖突了,那么調(diào)用 player Sprite 的 kill() 方法。因為我們只渲染了 all_sprites Group 中的 sprites ,kill() 方法將從其所在的全部 Groups 中移出 Sprite ,player就不再出現(xiàn),算是“殺死它了”。目前的完整代碼如下:

測試一下!

圖片

現(xiàn)在游戲可以玩了,但是長得挺丑的。接下來,我們將白色方塊變成有意思的圖片,讓游戲看上去有游戲的樣子。

前面的代碼示例中,我們使用了涂色的 Surface 對象表示游戲里的所有事物。雖然這樣有助于理解什么是 Surface 和它如何工作,但是卻讓游戲變得很丑!現(xiàn)在我們要給 player 和 enemy 添加一些圖片。我喜歡自己畫圖,我把 player 畫成小飛機,enemy 是導彈,這些可以從我的代碼庫中下載。歡迎你使用我的作品,自己畫或者者下載一些免費游戲素材。

修改對象的構(gòu)造函數(shù)

下面是我們現(xiàn)在的 player 構(gòu)造函數(shù):

新的構(gòu)造函數(shù)將會是這個樣子的:

我們想用一張圖片替代 Surface 對象。我們將使用 pygame.image.load() 導入圖片的路徑。load() 方法將會返回一個 Surface 對象。我們?nèi)缓笤谶@個 Surface 對象上調(diào)用 convert() 創(chuàng)建副本,這樣可以更快地將它畫在屏幕上。

接下來,我們在圖片上調(diào)用 set_colorkey() 方法。set_colorkey用于設置圖片的顏色,如果不設置 Pygame 會將圖片設置為透明。這里我選用白色,因為和飛機的背景色一致。RLEACCEL 是一個可選參數(shù),它有助于 PyGame 在非加速顯示器上更快地渲染。

最后,我們和之前一樣調(diào)用 rect() 對象:在圖片上調(diào)用 get_rect()。

對 enemy 構(gòu)造函數(shù)做同樣的操作:

現(xiàn)在的游戲雖然和以前一樣,但是比之前漂亮多啦!但是我仍然覺得它少了點什么東西。讓我們加點不斷漂浮的白云,這樣會有飛機劃過藍天的感覺。為此,我們需要遵循之前用過的一些原則。首先,我們創(chuàng)建 cloud 對象,畫上白云的照片,其 update() 方法讓它不停地向著屏幕左邊移動。然后,我們需要添加一個自定義事件,每隔一段時間就生成白云(我們還要將添加白云到 all_spritesgroup)。白云對象的實現(xiàn)如下:

上面的代碼看起來都很熟悉,下面這個事件創(chuàng)建代碼也一樣,我們將它放在 enemy 事件代碼下面:

ADDCLOUD = pygame.USEREVENT+2

pygame.time.set_timer(ADDCLOUD,1000)

現(xiàn)在為它們創(chuàng)建一個新的 Sprite.Group:

clouds = pygame.sprite.Group()

現(xiàn)在,在主循環(huán)中,我們需要開始監(jiān)聽ADDCLOUD事件。

下面的代碼:

將會變成這樣:

我們還要把 clouds 添加到 all_sprites Group 和新的 clouds Group 中。我們這么做,是因為我們使用 all_sprites 來渲染,使用 clouds 調(diào)用它們的 update 函數(shù)。也許你很好奇,為什么我們將它不添加到 enemies Group中;畢竟我們調(diào)用的是一樣的 update 函數(shù)。原因在于,我們不想檢測白云和飛機之間的沖突。我們的飛機要順暢地通過所有的云層?,F(xiàn)在剩下的就是調(diào)用 clouds Group 的 update() 方法了!

結(jié)語

大功告成!讓我們測試一下,效果應該是這樣的:

完整代碼可以在 GitHub 上的代碼庫獲?。∠M窘坛虒δ阌杏?!

點此查看原文

Python 翻譯組是EarlGrey@編程派發(fā)起成立的一個專注于 Python 技術內(nèi)容翻譯的小組,目前已有近 30 名 Python 技術愛好者加入。

翻譯組出品的內(nèi)容(包括教程、文檔、書籍、視頻)將在編程派微信公眾號首發(fā),歡迎各位 Python 愛好者推薦相關線索。

推薦線索,直接在編程派微信公眾號推文下留言即可。


python微信小游戲開發(fā)(從零開發(fā)一個小游戲:PyGame入門)

熱門課程推薦

熱門資訊

請綁定手機號

x

同學您好!

您已成功報名0元試學活動,老師會在第一時間與您取得聯(lián)系,請保持電話暢通!
確定