若是你沒有任何編程經驗,並且想嘗試一下學習編程開發,這個系列教程必定適合你,它將帶你學習最基本的Python語法,並讓你掌握小遊戲的開發技巧。你所須要的,就是付出一些時間和耐心來嘗試這些代碼和操做。
@[top]html
1 下載安裝 python
2 下載安裝VS code
編輯器
安裝時,要注意勾選 添加到path
3 安裝pygame模塊python
Terminal-New Teminal
】打開命令行終端,而後輸入命令python -m pip install --upgrade pip
,回車,等待完成。而後一樣輸入命令pip install pygame,等待完成安裝,可能須要幾分鐘
編程
在桌面上建立一個文件夾mygame
,而後在VSCode中使用菜單【File-Open Folder】,選擇mygame
文件夾,VSCode左側將會出現EXPLORER導航欄。windows
在左側導航欄中,【右鍵-New File】建立文件main.py
。數組
- 將下面的代碼粘貼到右側`main.py`文件中。
import pygame import sys pygame.display.set_mode([600,400]) while 1: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit()
在這裏我仍是要說一下,文中素材以及可執行代碼能夠加羣:456926667,獲取,這個是我建立的一個針對0基礎的夥伴一個交流羣,下個文章我會更新關於pycharm版本的打地鼠。dom
* 仍然【Terminal-New terminal】終端中輸入命令`python main.py`,這將運行咱們上面的代碼,看到彈出一個黑色窗口。
執行上面的操做的時候,VSCode的右下角會常常彈出一些提示,若是有【Install】字樣,能夠放心的點擊它進行安裝更多內容。編輯器
也能夠從左側欄點擊圖標打開【EXTENSIONS】,而後搜索@id:ms-python.python
,點擊找到的結果,右側再點擊【Install】按鈕進行安裝。安裝以後main.py
文件的右上角就會出現三角形運行按鈕,點擊它一樣能夠運行代碼,至關於終端中輸入python main.py
。工具
pip install ...
安裝命令太慢。Windows用戶,能夠從上面的網盤中下載pip.ini
文件,而後在【C盤-用戶-用戶名】文件夾下面建立pip
文件夾,再把下載的pip.ini
文件拷貝進去,此後再運行pip install ...
安裝速度就會快不少。學習
對於蘋果用戶就麻煩不少。先在終端執行cd ~
切換到用戶文件夾,而後執行mkdir .pip
建立.pip
文件夾,它是隱身的,咱們打開訪達,從菜單執行【前往-前往文件夾...】,前往~/.test
目錄,把下載的pip.conf
文件粘貼進去,搞定。測試
pip.ini
或者pip.conf
文件是把原來pip
默認從國外下載安裝改爲了從國內下載,因此速度會變快不少。
其中import
是導入咱們要使用的外部代碼模塊,pygame
固然是必須的,sys
是system系統
的簡寫,由於咱們的遊戲要運行在系統(windows或者蘋果macOS)上面,因此咱們會用到系統的一些命令,好比下面的sys.exit()
這個命令。
pyagme.display.set_mode([600,400])
,這裏的[600,400]
是一對數字組合在一塊兒的,叫二元數組,這裏它表示寬600,高400的一個矩形。整句話就是設置要彈出的窗口的大小,display顯示
,set設置
,mode模式
。
while 1:...當是1的時候,就...
,1在代碼裏面表示正確的、真的、存在的,相反,0表示錯誤、假的、不存在的。while 1:do something
那麼something就會作,若是while 0: do something
那麼就不會作了。
for ... sys.exit()
這一段暫時能夠不深究,只是固定格式。只要知道它表示遊戲程序運行結束的時候系統把窗口也關掉,清理好計算機不要留痕跡,exit退出
。
遊戲開發都有固定的套路,不管是打地鼠、憤怒的小鳥,仍是西瓜忍者,甚至是王者榮耀這樣的大型遊戲,他們大體都遵循下面幾個思路:
建立一個地圖場景,上面可能有些道具。
好比幾個地鼠洞,一些能夠放小豬的木盒子,甚至很是複雜的山谷地形,上面還有不少野怪。
這些地圖上的元素通常都是被動的,就是你不去靠近或招惹野怪的話,它們不會互相打起來自相殘殺,一樣,小鳥還沒發射的時候,木盒子也不會本身倒塌。
建立至少一個玩家能夠控制的元素,它能夠和地圖場景發生交互。
這個能夠被控制的元素咱們稱爲玩家角色。在打地鼠遊戲中這個角色就是一個錘子,憤怒的小鳥中這個角色實際上是彈弓,彈出的小鳥實際上是個道具,在王者榮耀遊戲中玩家的角色就是本身的英雄。
必需要有評判標準,用來衡量輸贏勝敗。
玩家控制的角色和地圖場景進行交互,發生反應,對應的也必需要有一個評判標準,好比計算3分鐘內擊中地鼠的次數,或者計算砸死的綠豬的數量,或者是打野怪得到的經驗,這些規則必定要清晰並且不能互相矛盾。
大多數遊戲都有輸贏勝敗,而勝敗每每本質上只是誰的積分首先達到某個臨界點。能夠是某個關鍵道具的變化,好比對戰遊戲中塔被摧毀,也能夠是玩家角色的屬性變化,好比格鬥遊戲中被擊殺;也能夠只是純粹的某項積分評比,用排行榜代替輸贏。
要可以在窗口內繪製圖形。
能夠是直接用代碼繪製幾何圖形,也能夠是載入圖片顯示內容。
要能用代碼控制每一個元素(道具和角色)的動畫。
動畫就是一組圖片不停地輪番變化。要能用代碼控制播放和中止每一個元素的動畫,還能在不一樣動畫之間快速切換。
可以接收用戶的控制,並藉此影響遊戲中的元素。
知道用戶何時按了鍵盤,何時點了鼠標,按了哪一個按鍵,鼠標左鍵仍是右鍵?咱們常常把這些操做稱之爲交互事件。
可以對遊戲中各類元素產生的有效數據進行計算和管理。
玩家角色一刀砍下去,怪物的血量減小了100點,這個就是數據,並且是頗有用的數據,沒有這個數據的話怪物可能永遠砍不死了。
有時候這些數據要保存好,讓用戶下一次打開遊戲的時候仍然看到本身的等級和裝備都還存在。有些時候這些數據要及時清理,好比新的一局又開始了,地圖上的道具和角色都要恢復原樣。
咱們能夠把經典的打地鼠遊戲簡化歸納爲:
核心玩法簡化成一句話就是:點擊隨機出現圖形。
咱們用一個藍色的圓形表明地鼠。那怎麼在窗口中繪製一個圓形呢?
能夠百度【pygame 畫圓圈】相似的關鍵字,能夠查到要使用pygame.draw.circle
語句,它的具體語法能夠從官方說明文檔中找到,英文版詳細說明點這裏。
咱們查到它的語法是:
pygame.draw.circle() circle(surface, color, center, radius) -> Rect
這表示draw.circle()
須要四個參數,分別是surface表面,color顏色,center中心點,radius半徑
。
咱們繼續看surface
參數的說明:
surface (Surface) -- surface to draw on
聽上去像是畫布,——先要有個畫布才能在上面畫圓。
點擊Surface連接,找到更進一步說明:
Surface((width, height), flags=0, depth=0, masks=None) -> Surface
結尾的->Surface
表示Surface((width....)
這句話能夠生成一個Surface表面,咱們能夠用下面的語句捕捉到這個生成的表面:
sur=pygame.Surface((600, 400)
這樣,sur
就是咱們生成的表面了。
再返回來看color
參數:
color (Color or int or tuple(int, int, int, [int])) -- color to draw with, the alpha value is optional if using a tuple (RGB[A])
很明顯它是表示畫什麼顏色的圓。tuple(int, int, int, [int])
表示這裏須要三個整數int
一塊兒表示顏色,RGB
是指red紅,green綠,blue藍,alpha透明度
:
clr=(0,0,255) #藍色
對於center
中心位置咱們也能夠用一樣的方法獲得,這裏的Vector2
表示二元向量,及橫向x和豎向y的位置:
pos=pygame.vector2(300,200) #窗口中央
參數都具有了,那麼就能夠開始畫圓了。運行下面的代碼:
import pygame import sys pygame.init() # 初始化 window = pygame.display.set_mode([600, 400]) # 設定窗口 sur = pygame.Surface([600, 400]) # 繪製背景容器 clr = (0, 0, 255) pos = (300,200) rad = 100 while 1: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() # 每幀循環執行的代碼 pygame.draw.circle(sur, clr, pos, 100# 繪製圓 # 刷新畫面 window.blit(sur, (0, 0)) pygame.display.flip()
注意這裏最底部刷新畫面的兩行,其中window.blit(sur, (0, 0))
表示把咱們繪製好的表面sur
刷新到window
窗口中;pygame.display.flip()
表示進行窗口刷新。
隨機出現就是隨機位置,咱們必須確保每一次花圓的pos
位置都不一樣,並且應該是固定的幾個地鼠洞位置。——別忘了咱們要作打地鼠遊戲。
假設有6個地鼠位置pos
分別是[200,200],[300,200],[400,200],[200,300],[300,300],[400,300]
,那麼如何隨機取到6箇中一個呢?也就是如何隨機取到1~6其中的一個數字便可。
咱們能夠百度【python 隨機數】查到須要使用random
模塊,這是python自帶的模塊,不須要再從新pip install
。
若是搜索【python random document】能夠查找到官方的語法說明,以下:
random.randint(a, b) Return a random integer N such that a <= N <= b. Alias for randrange(a, b+1).
這是說能夠隨機生成a
和b
之間的一個數字。也能夠從中文的菜鳥教程網
學習到這個知識。
新建一個test.py
文件,咱們進行測試:
import random a = random.randint(0, 5) print(a)
每次運行都能生成不一樣的數字。
繼續測試:
import random a = random.randint(0, 6) pos6=[[200,200],[300,200],[400,200],[200,300],[300,300],[400,300]] print(pos6[a])
這裏的pos6[a]
表示pos6
的六個位置中的第a
個。運行這個代碼就會每次生成不一樣的位置。
測試成功以後咱們把它拷貝到剛纔的畫圓代碼中,獲得:
import pygame import sys import random pygame.init() # 初始化 window = pygame.display.set_mode([600, 400]) # 設定窗口 sur = pygame.Surface([600, 400]) # 繪製背景容器 clr = (0, 0, 255) pos6 = [[200, 200], [300, 200], [400, 200], [ 200, 300], [300, 300], [400, 300]] # !!六個位置 rad = 100 while 1: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() # 每幀循環執行的代碼 sur.fill((0, 0, 0)) # !!用黑色覆蓋前一幀的畫面,實現刷新 a = random.randint(0, 5) # !!隨機0到5 pygame.draw.circle(sur, clr, pos6[a], 100) # !!使用隨機位置 # 刷新畫面 window.blit(sur, (0, 0)) pygame.display.flip()
注意新增了sur.fill...
一行,這是用黑色(0,0,0)
來清理掉上一幀的內容,避免出現多個圓。
上面的代碼運行以後會看到藍色的圓四處亂跳,太快了,咱們但願改變位置以後能停一下,等咱們錘它。
咱們須要畫面的圓每隔n幀再隨機變換一次,而不是如今的每幀都隨機變。思路是這樣的:咱們設定一個計數器,開始是0,每幀都給它增長1,就是0,1,2,3,4...
直到它增到到超過50,這時候咱們就改變圓的位置並同時把計數器重置爲0。
代碼以下:
import pygame import sys import random pygame.init() # 初始化 window = pygame.display.set_mode([600, 400]) # 設定窗口 sur = pygame.Surface([600, 400]) # 繪製背景容器 clr = (0, 0, 255) pos6 = [[200, 200], [300, 200], [400, 200], [ 200, 300], [300, 300], [400, 300]] # 六個位置 rad = 100 tick=0 #!!計數器 while 1: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() # 每幀循環執行的代碼 if tick>50: #每50次刷新變換一次 sur.fill((0, 0, 0)) # 用黑色覆蓋前一幀的畫面,實現刷新 a = random.randint(0, 5) # 隨機0到5 pygame.draw.circle(sur, clr, pos6[a], 100) # 使用隨機位置 tick=0 else: #!!不刷新變換的時候 tick=tick+1 #!!增長計數器 # 刷新畫面 window.blit(sur, (0, 0)) pygame.display.flip()
當用戶點擊畫面的時候,咱們要知道它點擊了哪裏,是否點擊到了咱們畫的圓上面。
百度搜索【pygame 點擊】能夠找到相關資源,也能夠直接在官方說明文檔中找到。
思路是咱們添加對event.type
事件類型的實時監測,一旦發現點擊事件就獲取位置座標。代碼以下:
import pygame import sys import random from pygame.locals import * # 引入鼠標事件類型 pygame.init() # 初始化 window = pygame.display.set_mode([600, 400]) # 設定窗口 sur = pygame.Surface([600, 400]) # 繪製背景容器 clr = (0, 0, 255) pos6 = [[200, 200], [300, 200], [400, 200], [ 200, 300], [300, 300], [400, 300]] # 六個位置 rad = 100 tick = 0 # !!計數器 pos = pos6[0] # !!在外面記錄圓的位置 while 1: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == MOUSEBUTTONDOWN: # !!若是是鼠標按下事件 mpos = pygame.mouse.get_pos() # !!獲取鼠標位置 print(mpos) # 每幀循環執行的代碼 if tick > 50: # 每50次刷新變換一次 sur.fill((0, 0, 0)) # 用黑色覆蓋前一幀的畫面,實現刷新 a = random.randint(0, 5) # 隨機0到5 pos = pos6[a] # !!更新外部記錄的圓的位置 pygame.draw.circle(sur, clr, pos, 100) # !!使用隨機位置 tick = 0 # 重置計數器 else: # !!不刷新變換的時候 tick = tick+1 # !!增長計數器 # 刷新畫面 window.blit(sur, (0, 0)) pygame.display.flip()
運行這個代碼,任意點擊屏幕上的時候就會打印出檔期鼠標點擊的位置。
知道當前圓的位置pos
,也知道當前點擊的位置mpos
,這樣咱們就能夠計算出兩點之間的距離,距離大於圓半徑的就是沒有點到地鼠,距離小於半徑的就是點到地鼠了。
百度搜索【pygame 兩點距離】能夠搜到一些計算距離的方法,咱們這裏使用pygame
官方提供的方法,測試下面代碼:
import pygame a=pygame.math.Vector2.length(pygame.math.Vector2(3,4)) print(a)
它會輸出5(勾三股四玄五)。這裏的(3,4)
是pos
和mpos
相減獲得的差。
把這個思路帶入原來的代碼,獲得:
import pygame import sys import random from pygame.locals import * # 引入鼠標事件類型 pygame.init() # 初始化 window = pygame.display.set_mode([600, 400]) # 設定窗口 sur = pygame.Surface([600, 400]) # 繪製背景容器 clr = (0, 0, 255) pos6 = [[200, 200], [300, 200], [400, 200], [ 200, 300], [300, 300], [400, 300]] # 六個位置 rad = 50 tick = 0 # 計數器 pos = pos6[0] # 外面記錄圓的位置 while 1: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == MOUSEBUTTONDOWN: # 若是是鼠標按下事件 mpos = pygame.mouse.get_pos() # 獲取鼠標位置 dis = pygame.math.Vector2( mpos[0]-pos[0], mpos[1]-pos[1]) # !!計算座標差 len = pygame.math.Vector2.length(dis) # !!計算距離 if len < rad: tick = 51 # !!當即變換位置 # 每幀循環執行的代碼 if tick > 50: # 每50次刷新變換一次 sur.fill((0, 0, 0)) # 用黑色覆蓋前一幀的畫面,實現刷新 a = random.randint(0, 5) # 隨機0到5 pos = pos6[a] # 更新外部記錄的圓的位置 pygame.draw.circle(sur, clr, pos, 100) # 使用隨機位置 tick = 0 # 重置計數器 else: # 不刷新變換的時候 tick = tick+1 # 增長計數器 # 刷新畫面 window.blit(sur, (0, 0)) pygame.display.flip()
在這裏咱們設定若是距離長度len
小於圓半徑rad
,那麼就當即設置tick=51
使它大於50,當即進行隨機位置變換。
截止到這裏運行上面的代碼,能夠實現隨機出現地鼠(圓)並可以點擊使它消失,這也實現了遊戲的最基本邏輯功能。後續咱們將進一步編寫更多內容,讓它更完善一些。
計算數字增長很容易,設定一個score=0
,而後擊中地鼠的時候增長1就能夠了。可是,如何把它顯示到屏幕上呢?
能夠百度搜索【pygame 顯示文字】而後就能夠找到大體方法,咱們先進行一些測試:
import pygame pygame.init() # 初始化 window = pygame.display.set_mode([600, 400]) # 設定窗口 # 顯示文字 pygame.font.init() # !!初始化文字 font = pygame.font.SysFont('微軟雅黑', 30) # !!設定字體和字號 sur = font.render("Hello World!!{}".format(999), False, (255, 0, 0)) # !!生成w文字表面 while 1: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() window.blit(sur, (200, 10)) # !!增長分數表面 pygame.display.flip()
這段代碼中能夠看到pygame繪製文字分三步:
pygame.font.init()
先要初始化pygame.font.SysFont('微軟雅黑', 30)
設定字體和字號大小font.render("Hello World!!{}".format(999), False, (255, 0, 0))
生成一個Surface表面window.blit(sur, (200, 10))
運行上面的代碼獲得一個窗口以下:
咱們根據這個經驗改進的代碼:
import pygame import sys import random from pygame.locals import * # 引入鼠標事件類型 pygame.init() # 初始化 window = pygame.display.set_mode([600, 400]) # 設定窗口 sur = pygame.Surface([600, 400]) # 繪製背景容器 clr = (0, 0, 255) pos6 = [[200, 200], [300, 200], [400, 200], [ 200, 300], [300, 300], [400, 300]] # 六個位置 rad = 50 tick = 0 # 計數器 pos = pos6[0] # 外面記錄圓的位置 # 分數 score = 0 # !!分數計數 pygame.font.init() # !!初始化文字 score_font = pygame.font.SysFont('微軟雅黑', 30) # !!設定字體和字號 score_sur = score_font.render(str(score), False, (255, 0, 0)) # !!生成計數表面 while 1: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == MOUSEBUTTONDOWN: # 若是是鼠標按下事件 mpos = pygame.mouse.get_pos() # 獲取鼠標位置 dis = pygame.math.Vector2( mpos[0]-pos[0], mpos[1]-pos[1]) # 計算座標差 len = pygame.math.Vector2.length(dis) # 計算距離 if len < rad: tick = 1000 # 當即變換位置 score = score+1 # 計分增長 # 每幀循環執行的代碼 if tick > 50: # 每50次刷新變換一次 score_sur = score_font.render( str(score), False, (255, 0, 0)) # !!從新生成分數文字表面 sur.fill((0, 0, 0)) # 用黑色覆蓋前一幀的畫面,實現刷新 a = random.randint(0, 5) # 隨機0到5 pos = pos6[a] # 更新外部記錄的圓的位置 pygame.draw.circle(sur, clr, pos, 50) # 使用隨機位置 tick = 0 # 重置計數器 else: # 不刷新變換的時候 tick = tick+1 # 增長計數器 # 刷新畫面 window.blit(sur, (0, 0)) window.blit(score_sur, (200, 10)) # !!增長分數表面 pygame.display.flip()
運行上面的代碼,能夠用鼠標點擊跳動的藍色圓,每次擊中就能得到1分,實時顯示在頂部。
關於文字的更多內容能夠參考官方文檔說明。
如今窗口中顯示的仍然是鼠標,而不是錘子,下面咱們來看如何把鼠標變爲一個特定的圖形。
pygame關於鼠標控制的模塊是pygame.mouse
,官方說明文檔看這裏。
咱們能夠用pygame.mouse.set_visible(False)
來隱藏鼠標,但這樣一來咱們就看不到鼠標沒法操做了。
不過沒關係,咱們以前還記得當鼠標點擊的時候有一個mpos = pygame.mouse.get_pos()
能夠獲取當前鼠標的位置,一樣咱們能夠在鼠標移動的時候獲取鼠標的位置,而後在這個位置上畫一個紅色圓圈表明鼠標。
測試下面的代碼:
import pygame from pygame.locals import * pygame.init() window = pygame.display.set_mode([600, 400]) pygame.mouse.set_visible(False) # 隱藏鼠標 sur = pygame.Surface([600, 400]) mpos = [300, 200] # 記錄鼠標位置 while 1: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == MOUSEMOTION: # 當鼠標移動的時候 mpos = pygame.mouse.get_pos() # 更新鼠標位置 sur.fill((0, 0, 0)) # 填充黑色 pygame.draw.circle(sur, (255, 0, 0), mpos, 10) # 在鼠標位置畫紅色圓 window.blit(sur, (0, 0)) pygame.display.flip()
運行這個代碼將,當鼠標劃到窗口上面的時候就會有一個紅點跟着鼠標移動,紅點代替了原來的指針。
咱們把這個紅點鼠標代碼放入到遊戲中,獲得下面的代碼:
import pygame import sys import random from pygame.locals import * # 引入鼠標事件類型 pygame.init() # 初始化 window = pygame.display.set_mode([600, 400]) # 設定窗口 sur = pygame.Surface([600, 400]) # 繪製背景容器 clr = (0, 0, 255) pos6 = [[200, 200], [300, 200], [400, 200], [ 200, 300], [300, 300], [400, 300]] # 六個位置 rad = 50 tick = 0 # 計數器 pos = pos6[0] # 外面記錄圓的位置 # 分數 score = 0 # 分數計數 pygame.font.init() # 初始化文字 score_font = pygame.font.SysFont('微軟雅黑', 30) # !!設定字體和字號 score_sur = score_font.render(str(score), False, (255, 0, 0)) # !!生成計數表面 # 鼠標 pygame.mouse.set_visible(False) # !!隱藏鼠標 mpos = [300, 200] # !!記錄鼠標位置 while 1: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == MOUSEBUTTONDOWN: # 若是是鼠標按下事件 mpos = pygame.mouse.get_pos() # 獲取鼠標位置 dis = pygame.math.Vector2( mpos[0]-pos[0], mpos[1]-pos[1]) # 計算座標差 len = pygame.math.Vector2.length(dis) # 計算距離 if len < rad: tick = 1000 # 當即變換位置 score = score+1 # 計分增長 elif event.type == MOUSEMOTION: # !!當鼠標移動的時候 mpos = pygame.mouse.get_pos() # !!更新鼠標位置 # 每幀循環執行的代碼 if tick > 50: # 每50次刷新變換一次 score_sur = score_font.render( str(score), False, (255, 0, 0)) # 從新生成分數文字表面 a = random.randint(0, 5) # 隨機0到5 pos = pos6[a] # 更新外部記錄的圓的位置 tick = 0 # 重置計數器 else: # 不刷新變換的時候 tick = tick+1 # 增長計數器 # 繪製鼠標 sur.fill((0, 0, 0)) # !用黑色覆蓋前一幀的畫面,實現刷新 pygame.draw.circle(sur, clr, pos, 50) # !使用隨機位置畫地鼠 pygame.draw.circle(sur, (255, 0, 0), mpos, 10) # !!在鼠標位置畫紅色圓 # 刷新畫面 window.blit(sur, (0, 0)) window.blit(score_sur, (200, 10)) # 增長分數表面 pygame.display.flip()
主義者了把sur.fill
和原來畫地鼠藍圓的代碼移到了下面,和畫鼠標紅點的代碼放在了一塊兒,這樣把繪圖內容放在一塊兒更加合理。
咱們有不少辦法限定每局的長度,好比計時限定1分鐘,或者限定地鼠跳出總計100次。咱們這裏使用第二種限制,跳出100次就結束並統計分數。
添加一個計數器times=0
,而後每次隨機位置都給它增長1,當times>100
的時候,咱們就結束遊戲並顯示結束畫面統計戰果。
具體的代碼沒有新的內容,很少解釋,直接上結果:
import pygame import sys import random from pygame.locals import * # 引入鼠標事件類型 pygame.init() # 初始化 window = pygame.display.set_mode([600, 400]) # 設定窗口 sur = pygame.Surface([600, 400]) # 繪製背景容器 clr = (0, 0, 255) pos6 = [[200, 200], [300, 200], [400, 200], [ 200, 300], [300, 300], [400, 300]] # 六個位置 rad = 50 tick = 0 # 計數器 pos = pos6[0] # 外面記錄圓的位置 # 分數 score = 0 # 分數計數 pygame.font.init() # 初始化文字 score_font = pygame.font.SysFont('微軟雅黑', 30) # !!設定字體和字號 score_sur = score_font.render(str(score), False, (255, 0, 0)) # !!生成計數表面 # 鼠標 pygame.mouse.set_visible(False) # !!隱藏鼠標 mpos = [300, 200] # !!記錄鼠標位置 times = 0 # 地鼠跳出的次數 times_max=10 #最屢次數 tick_max=15 #地鼠每次跳多少幀 while 1: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == MOUSEBUTTONDOWN: # 若是是鼠標按下事件 mpos = pygame.mouse.get_pos() # 獲取鼠標位置 dis = pygame.math.Vector2( mpos[0]-pos[0], mpos[1]-pos[1]) # 計算座標差 len = pygame.math.Vector2.length(dis) # 計算距離 if len < rad: tick = 1000 # 當即變換位置 score = score+1 # 計分增長 elif event.type == MOUSEMOTION: # !!當鼠標移動的時候 mpos = pygame.mouse.get_pos() # !!更新鼠標位置 if times > times_max: # 顯示結束畫面 sur.fill((0, 0, 0)) pygame.mouse.set_visible(True) sur.fill((0, 0, 0)) end_font = pygame.font.SysFont('微軟雅黑', 80) # !!設定字體和字號 end_sur = score_font.render("Your Score is:{}/{}!".format(score,times_max), False, (255, 0, 0)) # !!生成計數表面 window.blit(sur, (0, 0)) window.blit(end_sur, (100, 100)) # 增長分數表面 pygame.display.flip() else: # 每幀循環執行的代碼 if tick > tick_max: # 每50次刷新變換一次 times=times+1 #增長計次 score_sur = score_font.render( str(score), False, (255, 0, 0)) # 從新生成分數文字表面 a = random.randint(0, 5) # 隨機0到5 pos = pos6[a] # 更新外部記錄的圓的位置 tick = 0 # 重置計數器 else: # 不刷新變換的時候 tick = tick+1 # 增長計數器 # 繪製鼠標 sur.fill((0, 0, 0)) # !用黑色覆蓋前一幀的畫面,實現刷新 pygame.draw.circle(sur, clr, pos, 50) # !使用隨機位置畫地鼠 pygame.draw.circle(sur, (255, 0, 0), mpos, 10) # !!在鼠標位置畫紅色圓 # 刷新畫面 window.blit(sur, (0, 0)) window.blit(score_sur, (200, 10)) # 增長分數表面 pygame.display.flip()
運行這個代碼,用鼠標點擊藍圓,藍圓跳動10次以後結束,而後顯示擊中的次數。你能夠經過調整tick_max
的數字讓圓跳動的更快或更慢,調整times_max=100
來讓地鼠跳動100次後再結束。
如今咱們的地鼠遊戲已經有些模樣了,但還都是藍色紅色的圓圈和圓點,下一篇咱們來改變成爲圖片。
在上一節中咱們只使用了英文字體,怎麼顯示中文字體呢?
直接下載網盤裏面的文件,放在你的main.py
一塊兒,將原來的
score_font = pygame.font.SysFont('微軟雅黑', 30)
修改成:
score_font = pygame.font.Font('MicrosoftYaqiHeiLight-2.ttf', 30)
而後在render
裏面使用中文就能夠正常顯示了:
end_sur = score_font.render("你的得分:{}/{}!".format(score,times_max), False, (255, 0, 0))
另外,也可使用系統的中文字體,可是咱們不清楚系統裏面到底裝了哪些字體,能夠用
print(pygame.font.get_fonts())
將全部系統字體都打印出來,而後只能從名字猜出哪些是中文字體了,注意系統字體仍是要用font.SysFont
而不僅是font.Font
。
這是咱們的背景圖片dds-map.jpg
:
咱們能夠用map=pygame.image.load('dds-map.jpg')
把圖片讀取到代碼裏面。
更多官方關於圖片的操做說明看這裏
注意pygame.image.load()
獲得的是一個表面surface
,咱們能夠直接把它blit
到窗口wind
,也能夠把它blit
到。
這裏是完整代碼:
import pygame import sys import random from pygame.locals import * # 引入鼠標事件類型 pygame.init() # 初始化 window = pygame.display.set_mode([600, 400]) # 設定窗口 sur = pygame.Surface([600, 400]) # 繪製背景容器 clr = (0, 0, 255) posAll = [[100, 150], [300, 150], [500, 150], [ 200, 300], [400, 300]] # 六個位置 rad = 50 tick = 0 # 計數器 pos = posAll[0] # 外面記錄圓的位置 # 分數 score = 0 # 分數計數 pygame.font.init() # 初始化文字 score_font = pygame.font.Font('MicrosoftYaqiHeiLight-2.ttf', 30) # !!設定字體和字號 score_sur = score_font.render(str(score), False, (255, 0, 0)) # !!生成計數表面 # 鼠標 pygame.mouse.set_visible(False) # !!隱藏鼠標 mpos = [300, 200] # !!記錄鼠標位置 times = 0 # 地鼠跳出的次數 times_max=10 #最屢次數 tick_max=30 #地鼠每次跳多少幀 map=pygame.image.load('dds-map.jpg')#!!讀取圖片 while 1: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == MOUSEBUTTONDOWN: # 若是是鼠標按下事件 dis = pygame.math.Vector2( mpos[0]-pos[0], mpos[1]-pos[1]) # 計算座標差 len = pygame.math.Vector2.length(dis) # 計算距離 if len < rad: tick = 1000 # 當即變換位置 score = score+1 # 計分增長 elif event.type == MOUSEMOTION: # 當鼠標移動的時候 mpos = pygame.mouse.get_pos() # 更新鼠標位置 if times >= times_max: # 顯示結束畫面 sur.fill((0, 0, 0)) #!!結束時候仍然用黑色清空畫面 pygame.mouse.set_visible(True) end_font = pygame.font.Font('MicrosoftYaqiHeiLight-2.ttf',48) # !!設定字體和字號 end_sur = score_font.render("你的分數是:{}/{}!".format(score,times_max), True, (255, 0, 0)) # !!生成計數表面 window.blit(sur, (0, 0)) window.blit(end_sur, (100, 100)) # 增長分數表面 else: sur.blit(map, (0, 0)) #!!添加背景圖片 # 每幀循環執行的代碼 if tick > tick_max: # 每50次刷新變換一次 times=times+1 #增長計次 score_sur = score_font.render( "分數:{}/{}!".format(score,times), False, (255, 0, 0)) # 從新生成分數文字表面 a = random.randint(0, 4) # 隨機0到4 pos = posAll[a] # 更新外部記錄的圓的位置 tick = 0 # 重置計數器 else: # 不刷新變換的時候 tick = tick+1 # 增長計數器 # 繪製鼠標 pygame.draw.circle(sur, clr, pos, 50) # 使用隨機位置畫地鼠 pygame.draw.circle(sur, (255, 0, 0), mpos, 10) # !在鼠標位置畫紅色圓 # 刷新畫面 window.blit(sur, (0, 0)) window.blit(score_sur, (200, 10)) # 增長分數表面 pygame.display.flip() #刷新畫面
注意咱們先把圖片讀取,而後在每幀裏面決定是否使用。運行後以下圖:
地鼠和錘子各有兩個狀態,正常的地鼠和被擊打的地鼠,正常的錘子和砸下的錘子,以下圖所示(下圖沒法直接使用,請從網盤下載):
咱們能夠先把四個圖片都load
讀取進來成爲rat1,rat2,ham1,ham2
,而後咱們使用ratsur
和hamsur
表示真正要使用的表面,當鼠標按下的時候咱們設定hamsur=ham2
是砸下圖片,當鼠標點擊位置距離地鼠小於地鼠半徑的時候咱們使用ratsur=rat2
被砸中的圖片。最後咱們再分別把地鼠和錘頭blit
到sur
上面。
改造後的代碼以下:
import pygame import sys import random from pygame.locals import * # 引入鼠標事件類型 import time pygame.init() # 初始化 window = pygame.display.set_mode([600, 400]) # 設定窗口 sur = pygame.Surface([600, 400]) # 繪製背景容器 clr = (0, 0, 255) posAll = [[100, 150], [300, 150], [500, 150], [ 200, 300], [400, 300]] # 六個位置 rad = 50 tick = 0 # 計數器 pos = posAll[0] # 外面記錄圓的位置 # 分數 score = 0 # 分數計數 pygame.font.init() # 初始化文字 score_font = pygame.font.Font('MicrosoftYaqiHeiLight-2.ttf', 30) # !!設定字體和字號 score_sur = score_font.render(str(score), False, (255, 0, 0)) # !!生成計數表面 # 鼠標 pygame.mouse.set_visible(False) # !!隱藏鼠標 mpos = [300, 200] # !!記錄鼠標位置 times = 0 # 地鼠跳出的次數 times_max=10 #最屢次數 tick_max=30 #地鼠每次跳多少幀 map=pygame.image.load('dds-map.jpg')#!!讀取圖片 rat1=pygame.image.load('rat1.png')#!!讀取地鼠圖片 rat2=pygame.image.load('rat2.png')#!!讀取被砸地鼠圖片 ham1=pygame.image.load('hammer1.png')#!!讀取錘子圖片 ham2=pygame.image.load('hammer2.png')#!!讀取砸下錘子圖片 while 1: hamsur=ham1 ratsur=rat1 for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == MOUSEBUTTONDOWN: # 若是是鼠標按下事件 hamsur=ham2 #!!使用下落錘子 mpos = pygame.mouse.get_pos() # 獲取鼠標位置 dis = pygame.math.Vector2( mpos[0]-pos[0], mpos[1]-pos[1]) # 計算座標差 len = pygame.math.Vector2.length(dis) # 計算距離 if len < rad: tick = 1000 # 當即變換位置 score = score+1 # 計分增長 ratsur=rat2 #!!使用被砸地鼠 elif event.type == MOUSEMOTION: # 當鼠標移動的時候 mpos = pygame.mouse.get_pos() # 更新鼠標位置 if times >= times_max: # 顯示結束畫面 sur.fill((0, 0, 0)) #結束時候仍然用黑色清空畫面 pygame.mouse.set_visible(True) end_font = pygame.font.Font('MicrosoftYaqiHeiLight-2.ttf',48) # !!設定字體和字號 end_sur = score_font.render("你的分數是:{}/{}!".format(score,times_max), True, (255, 0, 0)) # !!生成計數表面 window.blit(sur, (0, 0)) window.blit(end_sur, (100, 100)) # 增長分數表面 else: sur.blit(map, (0, 0)) #添加背景圖片 # 每幀循環執行的代碼 if tick > tick_max: # 每50次刷新變換一次 times=times+1 #增長計次 score_sur = score_font.render( "分數:{}/{}!".format(score,times), False, (255, 0, 0)) # 從新生成分數文字表面 a = random.randint(0, 4) # 隨機0到4 pos = posAll[a] # 更新外部記錄的圓的位置 tick = 0 # 重置計數器 else: # 不刷新變換的時候 tick = tick+1 # 增長計數器 sur.blit(ratsur,(pos[0]-50,pos[1]-70)) #繪製地鼠 sur.blit(hamsur,(mpos[0]-50,mpos[1]-100)) #繪製錘頭 # 刷新畫面 window.blit(sur, (0, 0)) window.blit(score_sur, (200, 10)) # 增長分數表面 pygame.display.flip() #刷新畫面 time.sleep(0.04) #!!保持畫面一點時間
注意這裏的import time
和time.sleep(0.04)
這是讓每一幀停留一點點時間,0.04秒,每秒25幀(假設每幀畫圖不須要時間的話)。
另外咱們再blit
的時候使用了(pos[0]-50,pos[1]-50)
這樣的偏移,由於圖片老是用左上角做爲位置的起點,這樣偏移以後就變到了圖片中心,實際上咱們又故意讓地鼠和錘子更高一些,就使用了(pos[0]-50,pos[1]-70)
。
運行以後的樣子以下圖:
每次顯示最終成績以後,能不能讓遊戲3秒後從新開始呢?
咱們設定一個gameover=0
,遊戲結束後每幀都增長這個數字,若是gameover>100
,就是過了100幀,那麼咱們就從新開始。
從新開始必須意味着各類數據(分數,計時什麼的)和畫面都要重置到原來的狀態。
修改後的總體代碼以下:
import pygame import sys import random from pygame.locals import * # 引入鼠標事件類型 import time pygame.init() # 初始化 window = pygame.display.set_mode([600, 400]) # 設定窗口 sur = pygame.Surface([600, 400]) # 繪製背景容器 clr = (0, 0, 255) posAll = [[100, 150], [300, 150], [500, 150], [200, 300], [400, 300]] # 六個位置 rad = 50 tick = 0 # 計數器 pos = posAll[0] # 外面記錄圓的位置 # 分數 score = 0 # 分數計數 pygame.font.init() # 初始化文字 score_font = pygame.font.Font("MicrosoftYaqiHeiLight-2.ttf", 30) # !!設定字體和字號 score_sur = score_font.render(str(score), False, (255, 0, 0)) # !!生成計數表面 # 鼠標 pygame.mouse.set_visible(False) # !!隱藏鼠標 mpos = [300, 200] # !!記錄鼠標位置 times = 0 # 地鼠跳出的次數 times_max = 10 # 最屢次數 tick_max = 30 # 地鼠每次跳多少幀 map = pygame.image.load("dds-map.jpg") # !!讀取圖片 rat1 = pygame.image.load("rat1.png") # !!讀取地鼠圖片 rat2 = pygame.image.load("rat2.png") # !!讀取被砸地鼠圖片 ham1 = pygame.image.load("hammer1.png") # !!讀取錘子圖片 ham2 = pygame.image.load("hammer2.png") # !!讀取砸下錘子圖片 gameover = 0 #!!結束計時 gameover_max = 100 #!!結束計時最大值,超過這個值就從新開始 while 1: hamsur = ham1 ratsur = rat1 for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == MOUSEBUTTONDOWN: # 若是是鼠標按下事件 hamsur = ham2 # !!使用下落錘子 mpos = pygame.mouse.get_pos() # 獲取鼠標位置 dis = pygame.math.Vector2(mpos[0] - pos[0], mpos[1] - pos[1]) # 計算座標差 len = pygame.math.Vector2.length(dis) # 計算距離 if len < rad: tick = 1000 # 當即變換位置 score = score + 1 # 計分增長 ratsur = rat2 # !!使用被砸地鼠 elif event.type == MOUSEMOTION: # 當鼠標移動的時候 mpos = pygame.mouse.get_pos() # 更新鼠標位置 if times >= times_max: # 顯示結束畫面 sur.fill((0, 0, 0)) # 結束時候仍然用黑色清空畫面 pygame.mouse.set_visible(True) end_font = pygame.font.Font("MicrosoftYaqiHeiLight-2.ttf", 48) # !!設定字體和字號 end_sur = score_font.render( "你的分數是:{}/{}!".format(score, times_max), True, (255, 0, 0) ) # !!生成計數表面 sur.blit(end_sur, (100, 150)) cd = int((gameover_max - gameover) / 10) cd_sur = score_font.render( "從新開始倒計時{}".format(cd), True, (255, 0, 0) ) # !!生成計數表面 sur.blit(cd_sur, (100, 200)) # 增長分數表面 gameover = gameover + 1 #!!增長結束計時 else: sur.blit(map, (0, 0)) # 添加背景圖片 score_sur = score_font.render( "分數:{}/{}!".format(score, times + 1), False, (255, 0, 0) ) # 從新生成分數文字表面 sur.blit(score_sur, (200, 10)) # 增長分數表面 if tick > tick_max: # 每50次刷新變換一次 times = times + 1 # 增長計次 a = random.randint(0, 4) # 隨機0到4 pos = posAll[a] # 更新外部記錄的圓的位置 tick = 0 # 重置計數器 else: # 不刷新變換的時候 tick = tick + 1 # 增長計數器 if tick > 5: # 開始幾幀不顯示地鼠 sur.blit(ratsur, (pos[0] - 50, pos[1] - 70)) # 繪製地鼠 sur.blit(hamsur, (mpos[0] - 50, mpos[1] - 100)) # 繪製錘頭 # 刷新畫面 window.blit(sur, (0, 0)) pygame.display.flip() # 刷新畫面 time.sleep(0.04) # !!保持畫面一點時間 # !!重置遊戲 if gameover > gameover_max: pygame.mouse.set_visible(False) times = 0 score = 0 gameover = 0
運行這個代碼就能反覆玩遊戲了。
到這裏遊戲看上去好了不少,可是尚未背景音樂,打地鼠的時候也沒有音效,下一節咱們繼續添加聲音。
遊戲裏面的聲音分爲兩種,一種叫音樂music,另外一種叫音效sound。背景音樂是music,遊戲裏面的擊打聲點擊聲都是音效。同一時間播放的音樂通常只有一個,但音效能夠有不少個同時播放。
pygame可使用pygame.mixer.music.load('bg.mp3')
來載入foo.mp3音樂,而後pygame.mixer.music.play(0)
就能夠播放,這裏0表示播放1次,若是要無限次的播放則要改成-1.
可是若是要播放音效sound,那麼pygame裏面只能使用wav格式(而且不支持32位深,只支持16位深)。載入音效的方法是sd=pygame.mixer.Sound("hit.wav")
,播放是sd.play(0)
,這裏0也是1次,通常音效不須要連續播放。
咱們在遊戲一開始就能夠播放背景音樂了,但只有在點擊鼠標event.type == MOUSEBUTTONDOWN
的時候才播放錘子的聲音,只有在擊中地鼠的時候才播放地鼠的叫聲。
修改以後的代碼以下:
import pygame import sys import random from pygame.locals import * # 引入鼠標事件類型 import time pygame.init() # 初始化 window = pygame.display.set_mode([600, 400]) # 設定窗口 sur = pygame.Surface([600, 400]) # 繪製背景容器 clr = (0, 0, 255) posAll = [[100, 150], [300, 150], [500, 150], [200, 300], [400, 300]] # 六個位置 rad = 50 tick = 0 # 計數器 pos = posAll[0] # 外面記錄圓的位置 # 分數 score = 0 # 分數計數 pygame.font.init() # 初始化文字 score_font = pygame.font.Font("MicrosoftYaqiHeiLight-2.ttf", 30) # !!設定字體和字號 score_sur = score_font.render(str(score), False, (255, 0, 0)) # !!生成計數表面 # 鼠標 pygame.mouse.set_visible(False) # !!隱藏鼠標 mpos = [300, 200] # !!記錄鼠標位置 times = 0 # 地鼠跳出的次數 times_max = 10 # 最屢次數 tick_max = 30 # 地鼠每次跳多少幀 map = pygame.image.load("dds-map.jpg") # !!讀取圖片 rat1 = pygame.image.load("rat1.png") # !!讀取地鼠圖片 rat2 = pygame.image.load("rat2.png") # !!讀取被砸地鼠圖片 ham1 = pygame.image.load("hammer1.png") # !!讀取錘子圖片 ham2 = pygame.image.load("hammer2.png") # !!讀取砸下錘子圖片 gameover = 0 # !!結束計時 gameover_max = 100 # !!結束計時最大值,超過這個值就從新開始 # 音樂和音效 pygame.mixer.music.load("bg.mp3") # !!載入背景音樂 pygame.mixer.music.play(-1) # !!無限播放背景音樂 hitsound = pygame.mixer.Sound("hit.wav") # !!載入擊打聲音 hurtsound = pygame.mixer.Sound("aiyo2.wav") # !!載入地鼠叫聲 while 1: hamsur = ham1 ratsur = rat1 for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == MOUSEBUTTONDOWN: # 若是是鼠標按下事件 hamsur = ham2 # 使用下落錘子 hitsound.play() # !!播放擊打聲音 mpos = pygame.mouse.get_pos() # 獲取鼠標位置 dis = pygame.math.Vector2(mpos[0] - pos[0], mpos[1] - pos[1]) # 計算座標差 len = pygame.math.Vector2.length(dis) # 計算距離 if len < rad: tick = 1000 # 當即變換位置 score = score + 1 # 計分增長 ratsur = rat2 # 使用被砸地鼠 hurtsound.play() # !!播放地鼠聲音 elif event.type == MOUSEMOTION: # 當鼠標移動的時候 mpos = pygame.mouse.get_pos() # 更新鼠標位置 if times >= times_max: # 顯示結束畫面 sur.fill((0, 0, 0)) # 結束時候仍然用黑色清空畫面 pygame.mouse.set_visible(True) end_font = pygame.font.Font("MicrosoftYaqiHeiLight-2.ttf", 48) # 設定字體和字號 end_sur = score_font.render( "你的分數是:{}/{}!".format(score, times_max), True, (255, 0, 0) ) # 生成計數表面 sur.blit(end_sur, (100, 150)) cd = int((gameover_max - gameover) / 10) cd_sur = score_font.render( "從新開始倒計時{}".format(cd), True, (255, 0, 0) ) # 生成計數表面 sur.blit(cd_sur, (100, 200)) # 增長分數表面 gameover = gameover + 1 # !!增長結束計時 else: sur.blit(map, (0, 0)) # 添加背景圖片 score_sur = score_font.render( "分數:{}/{}!".format(score, times + 1), False, (255, 0, 0) ) # 從新生成分數文字表面 sur.blit(score_sur, (200, 10)) # 增長分數表面 if tick > tick_max: # 每50次刷新變換一次 times = times + 1 # 增長計次 a = random.randint(0, 4) # 隨機0到4 pos = posAll[a] # 更新外部記錄的圓的位置 tick = 0 # 重置計數器 else: # 不刷新變換的時候 tick = tick + 1 # 增長計數器 if tick > 5: # 開始幾幀不顯示地鼠 sur.blit(ratsur, (pos[0] - 50, pos[1] - 70)) # 繪製地鼠 sur.blit(hamsur, (mpos[0] - 50, mpos[1] - 100)) # 繪製錘頭 # 刷新畫面 window.blit(sur, (0, 0)) pygame.display.flip() # 刷新畫面 time.sleep(0.04) # 保持畫面一點時間 # 重置遊戲 if gameover > gameover_max: pygame.mouse.set_visible(False) times = 0 score = 0 gameover = 0
運行上面的代碼,能夠聽到歡快的背景音樂,點擊鼠標時候會有捶地聲音,打中地鼠會有哎呦的叫聲。
咱們寫的代碼目前只能在本身的電腦上運行,由於咱們先要安裝python,而後還要安裝pygame才行,這和咱們日常下載的軟件不一樣,下載的軟件能夠直接運行(或者安裝自身後運行)。
Python給咱們提供了自動把代碼打包成軟件的工具,Windows下推薦使用auto-py-to-exe工具。一樣先安裝pip install auto-py-to-exe
,而後只要執行auto-py-to-exe
就會打開一個窗口。
基本設置以下:
注意幾個地方:
main.py
.ico
文件,好比easyicon有不少,網盤裏面有一個地鼠圖標icon.ico
點擊OPEN OUTPUT FOLDER打開生產的軟件目錄(默認在你的代碼文件夾下面的output文件夾內),找到那個和你的Script Location同名的文件,點擊它就能夠運行遊戲了。
也能夠把這個MAIN.exe複製而後在桌面上粘貼快捷方式,之後只要點這個快捷方式就能夠了。
在網盤文件中包含一個main.rar文件,下載它而後解壓就能夠獲得我打包生成的軟件了。
關於Mac蘋果電腦下面生成軟件的方法暫時遇到一點麻煩,搞定以後再更新,敬請關注。
第一個小遊戲彷佛開發完成了,可是還有不少內容,咱們的代碼也有不少不合理的地方,下一篇咱們一塊兒來回顧和整理,而且繼續介紹更多小遊戲的開發方法。
遊戲裏面的聲音分爲兩種,一種叫音樂music,另外一種叫音效sound。背景音樂是music,遊戲裏面的擊打聲點擊聲都是音效。同一時間播放的音樂通常只有一個,但音效能夠有不少個同時播放。
pygame可使用pygame.mixer.music.load('bg.mp3')
來載入foo.mp3音樂,而後pygame.mixer.music.play(0)
就能夠播放,這裏0表示播放1次,若是要無限次的播放則要改成-1.
可是若是要播放音效sound,那麼pygame裏面只能使用wav格式(而且不支持32位深,只支持16位深)。載入音效的方法是sd=pygame.mixer.Sound("hit.wav")
,播放是sd.play(0)
,這裏0也是1次,通常音效不須要連續播放。
咱們在遊戲一開始就能夠播放背景音樂了,但只有在點擊鼠標event.type == MOUSEBUTTONDOWN
的時候才播放錘子的聲音,只有在擊中地鼠的時候才播放地鼠的叫聲。
修改以後的代碼以下:
import pygame import sys import random from pygame.locals import * # 引入鼠標事件類型 import time pygame.init() # 初始化 window = pygame.display.set_mode([600, 400]) # 設定窗口 sur = pygame.Surface([600, 400]) # 繪製背景容器 clr = (0, 0, 255) posAll = [[100, 150], [300, 150], [500, 150], [200, 300], [400, 300]] # 六個位置 rad = 50 tick = 0 # 計數器 pos = posAll[0] # 外面記錄圓的位置 # 分數 score = 0 # 分數計數 pygame.font.init() # 初始化文字 score_font = pygame.font.Font("MicrosoftYaqiHeiLight-2.ttf", 30) # !!設定字體和字號 score_sur = score_font.render(str(score), False, (255, 0, 0)) # !!生成計數表面 # 鼠標 pygame.mouse.set_visible(False) # !!隱藏鼠標 mpos = [300, 200] # !!記錄鼠標位置 times = 0 # 地鼠跳出的次數 times_max = 10 # 最屢次數 tick_max = 30 # 地鼠每次跳多少幀 map = pygame.image.load("dds-map.jpg") # !!讀取圖片 rat1 = pygame.image.load("rat1.png") # !!讀取地鼠圖片 rat2 = pygame.image.load("rat2.png") # !!讀取被砸地鼠圖片 ham1 = pygame.image.load("hammer1.png") # !!讀取錘子圖片 ham2 = pygame.image.load("hammer2.png") # !!讀取砸下錘子圖片 gameover = 0 # !!結束計時 gameover_max = 100 # !!結束計時最大值,超過這個值就從新開始 # 音樂和音效 pygame.mixer.music.load("bg.mp3") # !!載入背景音樂 pygame.mixer.music.play(-1) # !!無限播放背景音樂 hitsound = pygame.mixer.Sound("hit.wav") # !!載入擊打聲音 hurtsound = pygame.mixer.Sound("aiyo2.wav") # !!載入地鼠叫聲 while 1: hamsur = ham1 ratsur = rat1 for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == MOUSEBUTTONDOWN: # 若是是鼠標按下事件 hamsur = ham2 # 使用下落錘子 hitsound.play() # !!播放擊打聲音 mpos = pygame.mouse.get_pos() # 獲取鼠標位置 dis = pygame.math.Vector2(mpos[0] - pos[0], mpos[1] - pos[1]) # 計算座標差 len = pygame.math.Vector2.length(dis) # 計算距離 if len < rad: tick = 1000 # 當即變換位置 score = score + 1 # 計分增長 ratsur = rat2 # 使用被砸地鼠 hurtsound.play() # !!播放地鼠聲音 elif event.type == MOUSEMOTION: # 當鼠標移動的時候 mpos = pygame.mouse.get_pos() # 更新鼠標位置 if times >= times_max: # 顯示結束畫面 sur.fill((0, 0, 0)) # 結束時候仍然用黑色清空畫面 pygame.mouse.set_visible(True) end_font = pygame.font.Font("MicrosoftYaqiHeiLight-2.ttf", 48) # 設定字體和字號 end_sur = score_font.render( "你的分數是:{}/{}!".format(score, times_max), True, (255, 0, 0) ) # 生成計數表面 sur.blit(end_sur, (100, 150)) cd = int((gameover_max - gameover) / 10) cd_sur = score_font.render( "從新開始倒計時{}".format(cd), True, (255, 0, 0) ) # 生成計數表面 sur.blit(cd_sur, (100, 200)) # 增長分數表面 gameover = gameover + 1 # !!增長結束計時 else: sur.blit(map, (0, 0)) # 添加背景圖片 score_sur = score_font.render( "分數:{}/{}!".format(score, times + 1), False, (255, 0, 0) ) # 從新生成分數文字表面 sur.blit(score_sur, (200, 10)) # 增長分數表面 if tick > tick_max: # 每50次刷新變換一次 times = times + 1 # 增長計次 a = random.randint(0, 4) # 隨機0到4 pos = posAll[a] # 更新外部記錄的圓的位置 tick = 0 # 重置計數器 else: # 不刷新變換的時候 tick = tick + 1 # 增長計數器 if tick > 5: # 開始幾幀不顯示地鼠 sur.blit(ratsur, (pos[0] - 50, pos[1] - 70)) # 繪製地鼠 sur.blit(hamsur, (mpos[0] - 50, mpos[1] - 100)) # 繪製錘頭 # 刷新畫面 window.blit(sur, (0, 0)) pygame.display.flip() # 刷新畫面 time.sleep(0.04) # 保持畫面一點時間 # 重置遊戲 if gameover > gameover_max: pygame.mouse.set_visible(False) times = 0 score = 0 gameover = 0
運行上面的代碼,能夠聽到歡快的背景音樂,點擊鼠標時候會有捶地聲音,打中地鼠會有哎呦的叫聲。