這是一篇由教程團隊成員Julian Meyer發表的文章,一個12歲的python開發人員。你可以在Google+和Twitter上找到他。
你可曾想過如何創建視頻游戲嗎?它不像你想象的那么復雜!
在本教程中,您將創建一個簡單的游戲叫做兔子和獾,在這里作為英雄的兔子要保衛城堡反擊進攻的獾群。:O
寫這個游戲,你將使用Python。不,我指的並不是一條大蛇!:]
Python是一種計算機編程語言。我們就本教程選擇Python,Python是一種易於上手、有趣而且很容易學的語言。
如果你剛接觸Python,開始之前先檢出這本書 - 深入Python:怎樣像計算機科學家一樣思考,這將使你提升速度。
然后回到這里,准備開始—— 有一場小兔子和獾之間的戰爭即將發生。繼續閱讀將加入戰爭吧!
開始: 安裝Python
如果你想在Windows電腦上嘗試本教程,你需要安裝Python,記住要安裝2.7.3版本而不是3.3.0!運行完安裝程序后,在開始菜單程序文件夾中會有IDLE,運行IDL。
如果你使用Mac,Python已經安裝了!只需打開一個終端(/Applications/Utilities/Terminal.app),輸入python然后按回車。
注意:如果你從python.org安裝Python(如果你想獲得PyGame需要這樣做),那么你也需要在Mac上進入IDLE。它應該在“Applications/Python 2.7”文件夾內。
如果操作正確的話,你將會看到類似輸出:
1
2
3
4
|
Python
2.7
.
3
(v2.
7.3
:
70274d53c1dd
, Apr
9
2012
,
20
:
52
:
43
)
[GCC
4.2
.
1
(Apple Inc. build
5666
) (dot
3
)] on darwin
Type
"help"
,
"copyright"
,
"credits"
or
"license"
for
more information.
>>>
|
注意:如果你想退出Python提示窗(三個尖括號提示:>>>),你可以通過在提示窗里輸入exit()或按Ctrl+D。
一旦你在Python提示窗了,測試Python是否正常工作的話輸入print 1+1,然后按回車或換行,它將輸出2。你已經寫了你的第一個Python程序。
現在你知道Python工作正常,為使用Python寫游戲你需要安裝PyGame。
PyGame是一個使寫游戲變簡單的Python庫,它提供如圖像處理、聲音回放等你可以很容易添加都游戲中的功能。
到這來下載你系統適合的PyGame,確認你下載的是一個Python2.7版本。
注意:從上面鏈接下載的PyGame安裝文件不能與Apple的Mac上默認安裝的Python一起工作,為使用PyGame你需要從python.org上下載安裝Python,或者你可以通過MacPorts安裝Python和PyGame。
要檢驗PyGame安裝是否正確的話,打開IDLE或通過終端運行Python,在Python提示符處輸入import pygames,如果回車后沒有輸出的話你安裝成功了。
如果,另一方面,輸出了下附類似錯誤,PyGame沒有正確安裝。
1
2
3
4
5
6
7
8
|
Python
2.7
.
2
(default, Jun
20
2012
,
16
:
23
:
33
)
[GCC
4.2
.
1
Compatible Apple Clang
4.0
(tags
/
Apple
/
clang
-
418.0
.
60
)] on darwin
Type
"help"
,
"copyright"
,
"credits"
or
"license"
for
more information.
>>>
import
pygame
Traceback (most recent call last):
File
"<stdin>"
, line
1
,
in
<module>
ImportError: No module named pygame
>>>
|
如果你遇到類似的錯誤,在論壇上發出來我將幫助你讓它正常。
從文件運行Python代碼
雖然你可以在Python提示符下運行短的Python代碼,但如果你工作在一個大的程序(比如游戲)里,你可能想要將你的代碼保存到一個文件,這樣你就不必一遍又一遍地鍵入它了。
有幾種方法可以運行Python程序文件。一種方法是使用一個純文本編輯器,不如記事本(Windows)或TextEdit(Mac)。打開一個新的文本文件,輸入你的Python代碼(像print 1 + 1)。然后保存它為asXXX.py(XXX可以是任何描述性的文件名稱)。
使用Windows的話,通過雙擊這個文件來運行它。在Mac上,打開終端,輸入python,然后拖動你保存的文件到終端窗口並按Enter。
另一種方法是鍵入代碼類到IDLE,也就是你在這個教程中需要做的方式。運行IDLE - 只需在終端輸入IDLE。 然后選擇文,然后選擇File\New Window,會出現一個你可以輸入代碼的文本編輯器窗口。你可以通過File\Save保存你更改的代碼,通過運行Run\Run Module(F5)運行代碼。
請注意運行菜單只在你已有一個文件在編輯器窗口打開時有效。
添加游戲資源
你幾乎已經可以開始創建你的游戲了。但沒有一些震撼的圖像和聲音效果的游戲又算什么呢?我已經收集了游戲所需要的所的圖形和聲音效果並把它們壓縮成了一個ZIP存檔,你可以在這里下載。
下載文件后,在你的硬盤上創建一個游戲使用的文件夾,將resources文件夾解壓到這個文件夾中,這樣你的游戲文件夾有了名為resources的子文件夾,各種資源在resources文件夾里面分組顯示如下:
兔子和獾的游戲你已經准備就緒。:]
第一步:(編寫簡單的)Hello Bunny(嘿,兔子)
運行IDLE開發環境,向上一節提到的那樣,打開一個新的文本編輯窗。在編輯窗鍵入以下代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
# 1 - Import library
import
pygame
from
pygame.
locals
import
*
# 2 - Initialize the game
pygame.init()
width, height
=
640
,
480
screen
=
pygame.display.set_mode((width, height))
# 3 - Load images
player
=
pygame.image.load(
"resources/images/dude.png"
)
# 4 - keep looping through
while
1
:
# 5 - clear the screen before drawing it again
screen.fill(
0
)
# 6 - draw the screen elements
screen.blit(player, (
100
,
100
))
# 7 - update the screen
pygame.display.flip()
# 8 - loop through the events
for
event
in
pygame.event.get():
# check if the event is the X button
if
event.
type
=
=
pygame.QUIT:
# if it is quit the game
pygame.quit()
exit(
0
)
|
把它保存到你的游戲目錄下(即資源子目錄)並命名為itgame.py。
讓我們逐段分析以上代碼:
1. 導入PyGame庫。這一步讓你在你的程序中使用來自庫中的函數。
2. 初始化PyGame並設置顯示窗口。
3. 加載你想要給bunny使用的圖片。
4. 循環執行以下縮進的代碼。
5. 在繪圖前,將屏幕填充成黑色。
6. 將之前加載進來的bunny圖片以100*100的大小顯示在屏幕上。
7. 更新屏幕。
8. 檢查任何新事件如果有的話,否則轉到退出命令,退出程序。
注意:根據PyGame的文檔,你不需要調用pygame.quit()因為解析器關閉時會自動調用它。然而,至少在Mac OS上,這個游戲會在退出時掛起除非pygame.quite被調用。
如果現在運行這段代碼(在Idle菜單欄點擊 “Run\Run Module"),你應該可以看到一個如下所示的屏幕:
耶,兔子就顯示在屏幕上了,並准備做動作!
但是只有一只兔子顯示在一個黑漆漆的屏幕上,這個游戲看起來很嚇人且很孤單。接下來要做的就是稍微美化一下咯。
第二步:添加布景
我們首先給游戲場景添加背景圖片,可以通過調用一組screen.blit()來完成背景添加。
在代碼的#3 小節,載入角色圖像之后添加下面的代碼:
1
2
|
grass
=
pygame.image.load(
"resources/images/grass.png"
)
castle
=
pygame.image.load(
"resources/images/castle.png"
)
|
這些代碼載入圖片然后賦給指定的變量,然后把它們畫到屏幕上。但如果你檢查草地的圖片,你會發現它沒有覆蓋整個640 x 480的屏幕,所以你必須平鋪使草地的圖片完全覆蓋屏幕。
在#6小節的開始(把兔子畫在屏幕上之前),添加以下代碼到game.py:
1
2
3
4
5
6
7
|
for
x
in
range
(width
/
grass.get_width()
+
1
):
for
y
in
range
(height
/
grass.get_height()
+
1
):
screen.blit(grass,(x
*
100
,y
*
100
))
screen.blit(castle,(
0
,
30
))
screen.blit(castle,(
0
,
135
))
screen.blit(castle,(
0
,
240
))
screen.blit(castle,(
0
,
345
))
|
正如你所見,首先把x坐標通過for循環遞增,在這個循環中再把y坐標循環遞增,並且將草地畫在使用循環生成的x、y坐標上。緊接着的一組代碼只是將城堡畫在屏幕上。
你現在運行這個程序,你會看到像如下的結果:
從現在開始,變得好看點了! :]
第三步:讓兔子動起來
下面你需要添加一些真正的游戲元素,比如讓兔子響應鍵盤的按鍵。
要做到這一點,你需要實現好一個方法記錄哪一個鍵在某一時刻被按下。你可以簡單的使用一個數組保存在游戲需要使用的鍵的按下狀態。
添加如下代碼到game.py的#2小節結束(在你設了屏幕高和寬度之后):
1
2
|
keys
=
[
False
,
False
,
False
,
False
]
playerpos
=
[
100
,
100
]
|
這段代碼是非常明了。數組keys按WASD的順序記錄它們的狀態。數組的每個元素對應一個鍵,第一個是W,第二個是A等等。
playerpos變量定義程序開始繪制游戲角色的起始位置。因為這個游戲將移動游戲角色到不同的位置,設置一個儲存角色位置的變量,然后便可以簡單地將角色繪制到這個位置。
現在你需要修改現有的代碼來繪制角色,使用新的playerpos變量,將# 6的程序:
1
|
screen.blit(player, (
100
,
100
))
|
改為:
1
|
screen.blit(player, playerpos)
|
接下來,基於哪些按鍵被按下更新鍵數組,PyGame通過添加event.key事件使檢測按鍵很容易實現。
在# 8檢測event.type==pygame.QUIT之后,添加這些代碼(如果有塊縮進的話使用與pygame.QUIT相同的縮進級):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
if
event.
type
=
=
pygame.KEYDOWN:
if
event.key
=
=
K_w:
keys[
0
]
=
True
elif
event.key
=
=
K_a:
keys[
1
]
=
True
elif
event.key
=
=
K_s:
keys[
2
]
=
True
elif
event.key
=
=
K_d:
keys[
3
]
=
True
if
event.
type
=
=
pygame.KEYUP:
if
event.key
=
=
pygame.K_w:
keys[
0
]
=
False
elif
event.key
=
=
pygame.K_a:
keys[
1
]
=
False
elif
event.key
=
=
pygame.K_s:
keys[
2
]
=
False
elif
event.key
=
=
pygame.K_d:
keys[
3
]
=
False
|
哇!這里有很多行代碼,如果你把它按If語句拆分也不是很復雜的。
首先你要檢測一是否有鍵被按下或釋放,然后你需要檢測哪個鍵被按下或者釋放,如果被按下或者釋放的鍵是你要使用的鍵,根據鍵值更新相應的鍵變量。
最后,你需要更新playerpos變量作為鍵按下的響應,這太簡單了。
將下附代碼添加到game.py的末尾(使用相同的縮進級,使用和for循環相同的縮進級)
1
2
3
4
5
6
7
8
9
|
# 9 - Move player
if
keys[
0
]:
playerpos[
1
]
-
=
5
elif
keys[
2
]:
playerpos[
1
]
+
=
5
if
keys[
1
]:
playerpos[
0
]
-
=
5
elif
keys[
3
]:
playerpos[
0
]
+
=
5
|
這段代碼只是檢查哪個鍵被按下,然后添加或減去游戲角色的x或y位置(取決於按下的鍵)來移動游戲角色。
運行這個游戲,你會得到根以前一樣的角色。試一下按WASD鍵,哈哈,起效了!
第四步: 旋轉兔子
是的,你的兔子現在可以隨着你的按鍵移動,但用鼠標來旋轉兔子朝向到你選擇的方向豈不更酷,所以它不是所有時間都朝向一個方向。使用三角函數來實現,這很簡單。
看一下下面的圖解:
上圖中,如果(5,3)是兔子的位置,(2,4)是當前鼠標的位置,你可以通過對兩點間距離的不同應用atan2三角函數獲得旋轉角度(z)。當然,一旦你知道旋轉角,你可以輕松相應地旋轉兔子。:]
如果你對這部分有點困惑,不要擔心,你依然可以繼續。但這就是你應該在數學課上用功的原因!:]在游戲編程時你會一直使用這個東西。
現在你需要將這個原理應用到你的游戲上,為做到這一點,你可以使用PyGameSurface.rotate(度數)函數, 順便說一下,記住,Z值是弧度。:[
atan2函數在Python的math庫總,所有先在#1結尾處增加:
1
|
import
math
|
然后,將#6最后一行(player.blit這行)替換成下面的代碼:
1
2
3
4
5
6
|
# 6.1 - Set player position and rotation
position
=
pygame.mouse.get_pos()
angle
=
math.atan2(position[
1
]
-
(playerpos[
1
]
+
32
),position[
0
]
-
(playerpos[
0
]
+
26
))
playerrot
=
pygame.transform.rotate(player,
360
-
angle
*
57.29
)
playerpos1
=
(playerpos[
0
]
-
playerrot.get_rect().width
/
2
, playerpos[
1
]
-
playerrot.get_rect().height
/
2
)
screen.blit(playerrot, playerpos1)
|
讓我們梳理一下上面代碼的基本流程。首先獲取鼠標和游戲角色的位置,然后你對兩個位置應用atan2函數,之后,你將atan2返回的弧度轉化成度數(將弧度乘以近似57.29或360/2π)。
因為兔子會旋轉,它的位置也將會改變。所以現在計算兔子的新位置並把它顯示在屏幕。
再次運行這個游戲。如果你只按了“WASD”鍵,那么這個游戲應該和之前完全一樣,但如果你移動你的鼠標兔子也會隨之旋轉,酷!
第五步:射擊吧,兔子!
現在你的兔子已經可以自由活動了,是時候給它添加更多的動作了。讓兔子可以用劍射擊敵人怎么樣?它可不是只溫順的兔斯基!
這一步稍微有點復雜,因為你必須記錄所有射出的劍,更新它們的位置、旋轉並且在它們飛出屏幕后刪除它們。
首先,在初始化小節(#2小節)的結束添加必要的變量:
1
2
|
acc
=
[
0
,
0
]
arrows
=
[]
|
第一個變量記錄玩家的射擊精度,第二個變量記錄所有的劍。精度變量acc實際上是一個包含射擊數量和命中獾 次數的列表。最后我們可以使用這些信息來計算精度的百分比。
接下來,在section #3的末尾加載弓箭圖像:
1
|
arrow
=
pygame.image.load(
"resources/images/bullet.png"
)
|
現在當玩家點擊鼠標,弓箭就要射出。在section #8的末尾加入以下代碼作為新的事件句柄(event handler):
1
2
3
4
|
if
event.
type
=
=
pygame.MOUSEBUTTONDOWN:
position
=
pygame.mouse.get_pos()
acc[
1
]
+
=
1
arrows.append([math.atan2(position[
1
]
-
(playerpos1[
1
]
+
32
),position[
0
]
-
(playerpos1[
0
]
+
26
)),playerpos1[
0
]
+
32
,playerpos1[
1
]
+
32
])
|
這些代碼檢查是否有鼠標點擊,如果有它會讀取鼠標位置,並根據玩家的旋轉和指針的位置計算出弓箭的旋轉。這個旋轉儲存在arrows數組里。
接下來你需要真正在屏幕上畫出弓箭了。在section #6.1之后插入以下代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# 6.2 - Draw arrows
for
bullet
in
arrows:
index
=
0
velx
=
math.cos(bullet[
0
])
*
10
vely
=
math.sin(bullet[
0
])
*
10
bullet[
1
]
+
=
velx
bullet[
2
]
+
=
vely
if
bullet[
1
]<
-
64
or
bullet[
1
]>
640
or
bullet[
2
]<
-
64
or
bullet[
2
]>
480
:
arrows.pop(index)
index
+
=
1
for
projectile
in
arrows:
arrow1
=
pygame.transform.rotate(arrow,
360
-
projectile[
0
]
*
57.29
)
screen.blit(arrow1, (projectile[
1
], projectile[
2
]))
|
運用基本的三角函數可以計算出vely和velx。10是弓箭的速度。if語句檢查弓箭是否飛出邊界,如果是則刪除該弓箭。第二個for語句循環過arrows數組並畫出相應旋轉的弓箭。
試試運行程序。你應該有一只兔兔在你點擊鼠標時發射弓箭了。(。☉౪ ⊙。)
第六步:拿起武器!獾!
好的,你有了一個城堡和可以移動和射擊的英雄。但少了什么東西呢?攻擊城堡的敵人!
(炸掉你的城堡!)
在這個步驟中,你將創建幾只隨機生成並跑向城堡的獾。隨着游戲的進展會有越來越多的獾。所以,讓我們做一個列表看看需要做那些工作。
1、把壞家伙們添加到一個數組列表;
2、每幀每幀的更新這個數組並檢查他們是否都出現在屏幕上;
3、顯示這些壞家伙。
很容易,是吧?:]
首先,把下面這段代碼添加到section #2后面:
1
2
3
4
|
badtimer
=
100
badtimer1
=
0
badguys
=
[[
640
,
100
]]
healthvalue
=
194
|
上面這段代碼設置了一個計時器(以及其他一些值)以便每過一段時間在游戲中增加一只新的獾。你每幀每幀的減少 badtimer直到0, 然后就生成一個新的獾。
現在把下面這段代碼添加到section #3后面:
1
2
|
badguyimg1
=
pygame.image.load(
"resources/images/badguy.png"
)
badguyimg
=
badguyimg1
|
上面代碼的第一行類似於前面所有的圖片加載代碼。第二行代碼設置了一個圖片副本以便於這個壞家伙能更容易動起來。
下一步,你必須更新並且顯示這個壞家伙。把下面代碼添加到section #6.2之后:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
# 6.3 - Draw badgers
if
badtimer
=
=
0
:
badguys.append([
640
, random.randint(
50
,
430
)])
badtimer
=
100
-
(badtimer1
*
2
)
if
badtimer1>
=
35
:
badtimer1
=
35
else
:
badtimer1
+
=
5
index
=
0
for
badguy
in
badguys:
if
badguy[
0
]<
-
64
:
badguys.pop(index)
badguy[
0
]
-
=
7
index
+
=
1
for
badguy
in
badguys:
screen.blit(badguyimg, badguy)
|
仔細的看下這段代碼,:] 第一行檢查badtimer是否為0,以badtimer至今為止已經運行的次數為基礎,創建一個新的獾並再次設置badtimer。第一個for循環更新獾的X坐標,並檢查是否在屏幕上。如果不再屏幕上就刪除掉。第二個佛如循環繪制所有獾。
為了在上述代碼中使用隨機函數,我們必須引入 random 庫:
1
|
import
random
|
最后,在 while 語句后面添加下面一行代碼用來讓 badtimer 值減1:
1
|
badtimer
-
=
1
|
再次運行游戲來測試上述代碼,現在你將看到真正的游戲,你可以發射、移動、轉向,而且獾也嘗試跑向你。
但等等,為什么不是獾炸毀這座城堡嗎?馬上搞定!
在#6.3小節中每一個循環前的 index += 1 之前添加如下代碼:
1
2
3
4
5
6
7
8
|
# 6.3.1 - Attack castle
badrect
=
pygame.Rect(badguyimg.get_rect())
badrect.top
=
badguy[
1
]
badrect.left
=
badguy[
0
]
if
badrect.left<
64
:
healthvalue
-
=
random.randint(
5
,
20
)
badguys.pop(index)
# 6.3.3 - Next bad guy
|
這段代碼非常簡單,如果獾的x坐標值小於64,則刪除這家伙然后隨機遞減5到20點的城堡的生命值。(在后面你可以顯示生命值到屏幕上)
現在你構建並運行程序,你將看到一堆獾攻擊城堡后消失。雖然你不能看到但獾確實降低了城堡的生命值。
第七步:獾與箭的碰撞
現在獾可以攻擊你的城堡但你的箭卻對它們沒有任何效果!兔子該如何保護自己的家園?
是時候讓箭可以殺死獾,你才可以保護你的城堡贏得游戲!首先,你必須循環檢查每個壞蛋,在檢查時以需要循環檢查所有的箭是不是和獾碰撞了。如果箭碰到了獾則刪除箭和獾,並且遞增命中值。
在#6.3.1小節后添加如下代碼:
1
2
3
4
5
6
7
8
9
10
11
|
#6.3.2 - Check for collisions
index1
=
0
for
bullet
in
arrows:
bullrect
=
pygame.Rect(arrow.get_rect())
bullrect.left
=
bullet[
1
]
bullrect.top
=
bullet[
2
]
if
badrect.colliderect(bullrect):
acc[
0
]
+
=
1
badguys.pop(index)
arrows.pop(index1)
index1
+
=
1
|
這段代碼里有一個值得注意的地方,if語句后是PyGame內建的檢查兩個矩形是否相交的函數。其他語句只是按上面解釋運行。
如果你現在運行程序,你會發現已經可以射擊並殺死獾了。
第八步:添加生命值和時鍾顯示
游戲現在進展良好,有攻擊者和守衛者。現在你還需要一種方式顯示分數,看看這些兔子干得怎么樣。
最簡單的方式是添加一個HUD(平視顯示器)顯示當前城堡的健康狀況。也可以添加一個時鍾顯示城堡被保護了多久。
首先添加時鍾,在#7小節前添加如下代碼:
1
2
3
4
5
6
|
# 6.4 - Draw clock
font
=
pygame.font.Font(
None
,
24
)
survivedtext
=
font.render(
str
((
90000
-
pygame.time.get_ticks())
/
60000
)
+
":"
+
str
((
90000
-
pygame.time.get_ticks())
/
1000
%
60
).zfill(
2
),
True
, (
0
,
0
,
0
))
textRect
=
survivedtext.get_rect()
textRect.topright
=
[
635
,
5
]
screen.blit(survivedtext, textRect)
|
上面代碼簡單的使用PyGame默認字體創建字體並設置尺寸為24。然后使用字體渲染時間到表面上。之后廣西被定位並繪制到屏幕上。
下一步添加生命條。在繪制生命條之前你需要載入它的背景圖。添加如下代碼到#3小節結束:
1
2
|
healthbar
=
pygame.image.load(
"resources/images/healthbar.png"
)
health
=
pygame.image.load(
"resources/images/health.png"
)
|
第一個是紅色圖用來鋪滿生命條。第二個綠色圖顯示當前生命值。
現在添加如下代碼到#6.4節(你上一步添加的)之后來將生命條畫到屏幕上:
1
2
3
4
|
# 6.5 - Draw health bar
screen.blit(healthbar, (
5
,
5
))
for
health1
in
range
(healthvalue):
screen.blit(health, (health1
+
8
,
8
))
|
上面的代碼首先畫出全紅色的生命條,然后根據城堡的剩余的生命繪制綠色生命條。
現在你構建並運行程序,你可以看到時鍾和生命條。
第九步:判斷輸贏
這是什么?如果你玩得足夠久,即使你的命令值降到了0,游戲還是繼續!不僅僅如此,你也還可以繼續射擊獾。這應該行不通的,但現在就是這樣。你需要添加某種贏/輸形式的場景讓這個游戲值得玩。
所以我們現在添加輸贏條件和各自的畫面。你可以退出主游戲循環並進入輸贏界面的循環。在輸贏循環中,你可以檢查用戶是輸了還是贏了,並顯示相應的界面。
下面是一個判斷輸贏的基本方法:
如果超過了時間(90000毫秒或90秒):
- 停止運行游戲
- 設置游戲的結果為贏了
如果城堡被摧毀了:
- 停止運行游戲
- 設置游戲結果為輸了
計算准確度的方法。
注:使用acc[0]*1.0 只是將acc[0]轉換成float浮點類型,如果你不這么轉換,則除法操作將返回一個整數值比如1或2而不是1.5。
將下面的代碼加到game.py末尾:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
#10 - Win/Lose check
if
pygame.time.get_ticks()>
=
90000
:
running
=
0
exitcode
=
1
if
healthvalue<
=
0
:
running
=
0
exitcode
=
0
if
acc[
1
]!
=
0
:
accuracy
=
acc[
0
]
*
1.0
/
acc[
1
]
*
100
else
:
accuracy
=
0
# 11 - Win/lose display
if
exitcode
=
=
0
:
pygame.font.init()
font
=
pygame.font.Font(
None
,
24
)
text
=
font.render(
"Accuracy: "
+
str
(accuracy)
+
"%"
,
True
, (
255
,
0
,
0
))
textRect
=
text.get_rect()
textRect.centerx
=
screen.get_rect().centerx
textRect.centery
=
screen.get_rect().centery
+
24
screen.blit(gameover, (
0
,
0
))
screen.blit(text, textRect)
else
:
pygame.font.init()
font
=
pygame.font.Font(
None
,
24
)
text
=
font.render(
"Accuracy: "
+
str
(accuracy)
+
"%"
,
True
, (
0
,
255
,
0
))
textRect
=
text.get_rect()
textRect.centerx
=
screen.get_rect().centerx
textRect.centery
=
screen.get_rect().centery
+
24
screen.blit(youwin, (
0
,
0
))
screen.blit(text, textRect)
while
1
:
for
event
in
pygame.event.get():
if
event.
type
=
=
pygame.QUIT:
pygame.quit()
exit(
0
)
pygame.display.flip()
|
這是截至目前最長的代碼塊,但不是最復雜的。
第一個if語句檢查是否到時間,第二個檢查城堡是否被摧毀,第三個計算你的准確率。之后,一個快速的if語句檢查你是勝利還是失敗了,並顯示正確的圖像。
當然,如果你想顯示勝利與失敗的屏幕圖像,那么這些圖像必須先被加載。將下面的代碼添加到# 3結束的地方:
1
2
|
gameover
=
pygame.image.load(
"resources/images/gameover.png"
)
youwin
=
pygame.image.load(
"resources/images/youwin.png"
)
|
另一點,更改#4處:
1
2
3
|
# 4 - keep looping through
while
1
:
badtimer
-
=
1
|
更改為:
1
2
3
4
5
|
# 4 - keep looping through
running
=
1
exitcode
=
0
while
running:
badtimer
-
=
1
|
running變量跟蹤游戲是否結束,exitcode變量跟蹤玩家是贏了還是輸了。
再次運行游戲,現在你可以嘗試勝利或死亡!酷!:]
第10步: 免費的音樂和聲音效果!
這個游戲看起來相當棒,可是有聲音嗎?是不是太安靜了點呢?增加一點點音效會讓整個游戲的感覺變得更棒。
PyGame 加載並播放聲音的方法非常簡單。首先你需要初始化混音器,代碼如下:
1
|
pygame.mixer.init()
|
然后加載要播放的聲音,並設置音量大小:
1
2
3
4
5
6
7
8
9
10
|
# 3.1 - Load audio
hit
=
pygame.mixer.Sound(
"resources/audio/explode.wav"
)
enemy
=
pygame.mixer.Sound(
"resources/audio/enemy.wav"
)
shoot
=
pygame.mixer.Sound(
"resources/audio/shoot.wav"
)
hit.set_volume(
0.05
)
enemy.set_volume(
0.05
)
shoot.set_volume(
0.05
)
pygame.mixer.music.load(
'resources/audio/moonlight.wav'
)
pygame.mixer.music.play(
-
1
,
0.0
)
pygame.mixer.music.set_volume(
0.25
)
|
最上代碼中大多數是簡單加載音頻文件和配置的音頻音量,但要注意pygame.mixer.music.load這一行——這一行加載游戲的背景音樂,下一行設置背景音樂一直重復。
注意音頻配置。:] 現在,你所需要做的就是按需要播放各種聲音效果。像下面每段注釋代碼那樣做:
1
2
3
4
5
6
|
# section 6.3.1 after if badrect.left<64:
hit.play()
# section 6.3.2 after if badrect.colliderect(bullrect):
enemy.play()
# section 8, after if event.type==pygame.MOUSEBUTTONDOWN:
shoot.play()
|
多次運行游戲,你會發現你現在有碰撞的背景音樂和射擊的聲音效果,游戲讓人感覺更逼真了!:]
從哪里開始?
你應該為自己感到自豪:你剛剛創建完成一個有趣的游戲,里面充滿了音樂,音效,一個殺手兔子,神風特攻隊獾和更多東西。我告訴你你可以做到!:]
你可以在這里下載最終的游戲源代碼。
這時,在游戲中隨意拓展你的創造力!也許可以試着換成與你自己的繪畫風格,或添加不同的武器或不同類型的怪物到游戲中!
在完成這個教程中你有問題或評論嗎? 如果有,請加入我們論壇的討論中! 我很期待你的來信。