第八天 項(xiàng)目實(shí)戰(zhàn)練習(xí)(3)
今天計(jì)劃繼續(xù)利用編寫一個(gè)游戲,來加強(qiáng)對基礎(chǔ)知識(shí)學(xué)習(xí)的理解。依然使用Pygame框架進(jìn)行學(xué)習(xí)错沃。昨天已經(jīng)列出了Pygame中的模塊列表季俩,然后
在測試游戲編程時(shí)遇到了坑钮糖,后來升級(jí)一下Python的版本就好了。在官網(wǎng)下載最新的pkg安裝包安裝后即可种玛。學(xué)習(xí)項(xiàng)目及練習(xí)源碼地址:
GitHub源碼
基礎(chǔ)模塊簡介
display模塊介紹
-
set_mode
set_mode會(huì)返回一個(gè)Surface對象藐鹤,代表了在桌面上出現(xiàn)的那個(gè)窗口瓤檐,三個(gè)參數(shù)第一個(gè)為元祖,代表分 辨率(必須)娱节;第二個(gè)是一個(gè)標(biāo)志位挠蛉,具體意思見下表,如果不用什么特性肄满,就指定0谴古;第三個(gè)為色深.
標(biāo)識(shí)位 功能 FULLSCREEN 創(chuàng)建一個(gè)全屏窗口 DOUBLEBUF 創(chuàng)建一個(gè)“雙緩沖“窗口,建議在HWSURFACE或OPENGL時(shí)使用 HWSURFACE 創(chuàng)建一個(gè)硬件加速窗口稠歉,必須和FULLSCREEN同時(shí)使用 OPENGL 創(chuàng)建一個(gè)OPENGL渲染的窗口 RESIZABLE 創(chuàng)建一個(gè)可以改變大小的窗口 NOFRAME 創(chuàng)建一個(gè)沒有邊框的窗口 -
set_caption
設(shè)置窗口標(biāo)題
-
convert
將圖像數(shù)據(jù)都轉(zhuǎn)化為Surface對象掰担,每次加載完圖像以后就應(yīng)該做這件事件(事實(shí)上因?yàn)?它太常用了,如果你不寫pygame也會(huì)幫你做)怒炸;
-
convert_alpha
相比convert带饱,保留了Alpha 通道信息(可以簡單理解為透明的部分),這樣我們的光標(biāo)才可以是不規(guī)則的形狀阅羹。
-
blit
是個(gè)重要函數(shù)勺疼,第一個(gè)參數(shù)為一個(gè)Surface對象,第二個(gè)為左上角位置捏鱼。
-
update
刷新窗口
pygame中的事件
事件是什么执庐,其實(shí)從名稱來看我們久能想到些什么,而且你所想到的基本就是事件的真正意思了导梆。游戲程序轨淌,一般會(huì)一直運(yùn)行下去,它會(huì)知道你關(guān)閉窗口而產(chǎn)生一個(gè)QUIT事件看尼。Pygame會(huì)接受用戶的各種操作(比如按鍵盤递鹉,移動(dòng)鼠標(biāo)等)產(chǎn)生事件。事件隨時(shí)可能發(fā)生狡忙,而且量也可能會(huì)很大梳虽,Pygame的做法是把一系列的事件存放一個(gè)隊(duì)列里,逐個(gè)的處理灾茁。
事件檢索
-
pygame.event.get()
它處理所有的事件窜觉,這好像打開大門讓所有的人進(jìn)入。
-
pygame.event.wait()
Pygame就會(huì)等到發(fā)生一個(gè)事件才繼續(xù)下去北专,就好像有哨兵把守的門一樣禀挫,來一個(gè)進(jìn)一個(gè)。
-
pygame.event.poll()
它會(huì)根據(jù)現(xiàn)在的情形返回一個(gè)真實(shí)的事件拓颓,或者一個(gè)“什么都沒有”语婴。
常用事件集
事件 | 產(chǎn)生途徑 | 參數(shù) |
---|---|---|
QUIT | 用戶按下關(guān)閉按鈕 | none |
ATIVEEVENT | Pygame被激活或者隱藏 | gain, state |
KEYDOWN | 鍵盤被按下 | unicode, key, mod |
KEYUP | 鍵盤被放開 | key, mod |
MOUSEMOTION | 鼠標(biāo)移動(dòng) | pos, rel, buttons |
MOUSEBUTTONDOWN | 鼠標(biāo)按下 | pos, button |
MOUSEBUTTONUP | 鼠標(biāo)放開 | pos, button |
JOYAXISMOTION | 游戲手柄 | (Joystick or pad)移動(dòng) joy, axis, value |
JOYBALLMOTION | 游戲球 | (Joy ball)移動(dòng) joy, axis, value |
JOYHATMOTION | 游戲手柄 | (Joystick)移動(dòng) joy, axis, value |
JOYBUTTONDOWN | 游戲手柄按下 | joy, button |
JOYBUTTONUP | 游戲手柄放開 | joy, button |
VIDEORESIZE | Pygame窗口縮放 | size, w, h |
VIDEOEXPOSE | Pygame窗口部分公開 | (expose) none |
USEREVENT | 觸發(fā)了一個(gè)用戶事件 | code |
處理鼠標(biāo)事件
MOUSEMOTION事件會(huì)在鼠標(biāo)動(dòng)作時(shí)發(fā)生,它有三個(gè)參數(shù):
- buttons:一個(gè)含有三個(gè)數(shù)字的元組,三個(gè)值分別代表左鍵砰左、中鍵和右鍵匿醒,1就是按下了。
- pos:鼠標(biāo)光標(biāo)的位置
- rel:代表了現(xiàn)在距離上次產(chǎn)生鼠標(biāo)事件時(shí)的距離
和MOUSEMOTION類似的缠导,我們還有MOUSEBUTTONDOWN和MOUSEBUTTONUP兩個(gè)事件廉羔,看名字就知道什么意思了。很多時(shí)候僻造,你只需要知道鼠標(biāo)點(diǎn)下就可以了憋他,那就可以不用上面那個(gè)比較強(qiáng)大(也比較復(fù)雜)的事件了。它們的參數(shù)為:
- button:看清楚了少了個(gè)s髓削,這個(gè)值代表了哪個(gè)按鍵被操作
- pos:鼠標(biāo)光標(biāo)的位置
處理鍵盤事件
鍵盤和游戲手柄的事件比較類似竹挡,為KEYDOWN和KEYUP。
KEYDOWN和KEYUP的參數(shù)秒速如下:
- key -按下或者放開的鍵值立膛,是一個(gè)數(shù)字揪罕,估計(jì)地球上很少有人可以記住,所以Pygame中你可以使用K_xxx來表示旧巾,比如字母a就是K_a耸序,還有K_SPACE和K_RETURN等。
- mod -包含了組合鍵信息鲁猩,如果mod & KMOD_CTRL是真值,表示用戶同時(shí)按下了Ctrl鍵罢坝。類似的還有KMOD_SHIFT廓握,KMOD_ALT。
- unicode -代表了按下鍵的Unicode值嘁酿。
事件過濾
并不是所有的事件都需要處理的隙券,就好像不是所有登門造訪的人都是我們歡迎的一樣。比如闹司,俄羅斯方塊就無視你的鼠標(biāo)娱仔,而在游戲場景切換的時(shí)候,你按什么都是徒勞的游桩。我們應(yīng)該有一個(gè)方法來過濾掉一些我們不感興趣的事件(當(dāng)然我們可以不處理這些沒興趣的事件牲迫,但最好的方法還是讓它們根本不進(jìn)入我們的事件隊(duì)列),我們使用pygame.event.set_blocked(事件名)來完成借卧。如果有好多事件需要過濾盹憎,可以傳遞一個(gè)列表,比如pygame.event.set_blocked([KEYDOWN, KEYUP]),如果你設(shè)置參數(shù)None铐刘,那么所有的事件都被打開了陪每。與之相對的,我們使用pygame.event,set_allowed()來設(shè)定允許的事件。
產(chǎn)生事件
通常玩家做什么檩禾,Pygame就產(chǎn)生對應(yīng)的事件就可以了挂签,不過有的時(shí)候我們西藥模擬出一些事件來,不如錄像回放的時(shí)候盼产,我們就要把用戶的操作再現(xiàn)一遍饵婆。
import pygame
from pygame.locals import *
me_event = pygame.event.Event(KEYDOWN, {"key": K_SPACE, "mod": 0, "unicode": u''})
pygame.event.post(me_event) # 出發(fā)事件
使用字頭模塊
一個(gè)游戲,再怎么寒磣也得有文字辆飘,俄羅斯方塊還有個(gè)計(jì)分?jǐn)?shù)得呢啦辐。pygame可以直接調(diào)用系統(tǒng)字體,或者也可以使用TTF字體蜈项。為了使用字體芹关,你得先創(chuàng)建一個(gè)Font對象,對于系統(tǒng)自帶的字體紧卒。
my_font = pygame.font.SysFont("arial", 16)
第一個(gè)參數(shù)是字體名侥衬,第二個(gè)自然就是大小,一般來說“Arial”字體在很多系統(tǒng)都是存在的跑芳,如果找不到的畫轴总,就會(huì)使用一個(gè)默認(rèn)字體,這個(gè)默認(rèn)字體和滅個(gè)操作系統(tǒng)相關(guān)博个,你也可以使用pygame.font.get_fonts()來獲取當(dāng)前系統(tǒng)所有的可用字體怀樟。還有一個(gè)更好的方法,使用TTF的方法:
my_font = pygame.font.Font("my_font.ttf", 16)
這個(gè)語句使用了一個(gè)叫做“my_font.ttf”盆佣,這個(gè)方法之所以好是因?yàn)槟憧梢园炎煮w文件隨游戲文件一起分發(fā)往堡,避免用戶機(jī)器上沒有需要的字體,一旦你創(chuàng)建了一個(gè)字體對象共耍,你就可以使用render方法來寫字了虑灰,然后久能blit到屏幕上。
text_surface = my_font.render("Pyame is cool!", True, (0, 0, 0), (255, 255, 255))
第一個(gè)參數(shù)是寫的文字痹兜,第二個(gè)參數(shù)是個(gè)布爾值(代表是否開啟抗鋸齒)穆咐,就是說True的話字體會(huì)比較平滑,不過相應(yīng)的速度會(huì)有一點(diǎn)點(diǎn)的影響字旭;第三個(gè)是字體顏色对湃;第四個(gè)是背景色,如果你不想有背景色(也就是透明)谐算,那么可以不加這第四個(gè)參數(shù)熟尉。
追加說明一下如何顯示中文。簡單來說洲脂,首先你得用一個(gè)可以使用中文的字體斤儿,宋體剧包、黑體什么的,或者你可以直接用中文的TTF文件呢往果,然后文字使用Unicode疆液,即u“中文的文字”。最后不要忘了在源文件里加上一句關(guān)于文件編碼的“魔法注釋”陕贮,比如:
# _*_coding:utf-8_*_
像素
湊近顯示器堕油,你能看到圖像是由一個(gè)一個(gè)點(diǎn)構(gòu)成,這就是像素(如果能夠熟練的使用PS的肮之,對像素的了解就能更透徹了)掉缺。至于屏幕分辨率的意義,也就不用多說了戈擒,一個(gè)1280x1024的顯示器眶明,有著1310720個(gè)像素,一般為32的RGB系統(tǒng)筐高,每個(gè)像素就可以顯示16.7百萬種顏色搜囱。
動(dòng)起來 - 理解幀率
FPS(Frame Per Second)是游戲和硬件間較量的永恒話題,我也不想多插話了柑土,相信玩游戲的朋友都知道蜀肘。
只是記住幾個(gè)常用的量:一般的電視畫面是24FPS;30FPS基本可以給玩家提供流程的體驗(yàn)了稽屏;LCD的話扮宠,60FPS是常用的刷新率,所以你的游戲的幀率再高也就沒什么意義了狐榔;而絕大多數(shù)地球人都無法分辨70FPS以上的畫面了涵卵!
播放音樂
在Pygame里播放音頻有兩個(gè)方法,一個(gè)用來播放特效聲音荒叼,一個(gè)用來播放背景音樂:
pygame.mixer.Sound(filename)
該方法返回一個(gè)Sound 對象,調(diào)用它的.play( )方法典鸡,即可播放較短的音頻文件(比如玩 家受到傷害被廓、收集到金幣等);
pygame.mixer.music.load(filename)
該方法用來加載背景音樂,之后調(diào)用 pygame.mixer.music.play( )方法就可以播放背景音樂(Pygame只允許加載一個(gè)背景音樂在同一個(gè)時(shí)刻)
實(shí)戰(zhàn)一個(gè)游戲(坦克大戰(zhàn))
本游戲主要分為兩個(gè)對象萝玷,分別是我方坦克和敵方坦克嫁乘。用戶可以通過控制我方的坦克來摧毀敵方的坦克保護(hù)自己的“家”,把所有的敵方坦克消滅完達(dá)到勝利球碉。敵方的坦克在初 始的時(shí)候是默認(rèn) 5 個(gè)的(這可以自己設(shè)置)蜓斧,當(dāng)然,如果我方坦克被敵方坦克的子彈打中睁冬,游戲結(jié)束挎春。
分析
游戲中需要哪些類呢看疙?
- 主類:主要包括開始游戲、結(jié)束游戲的功能
- 坦克類:主要包括坦克的創(chuàng)建直奋、顯示能庆、移動(dòng)及射擊的功能
- 我方坦克類繼承坦克類,主要包括創(chuàng)建脚线、與敵方坦克的碰撞方法搁胆。
- 敵方坦克類繼承坦克類,主要包括創(chuàng)建邮绿、與我方坦克碰撞方法渠旁。
- 子彈類:主要包括子彈的創(chuàng)建、顯示及移動(dòng)的功能船逮。
- 墻壁類:主要包括墻壁的創(chuàng)建顾腊、顯示的功能。
- 爆炸效果類:主要展示爆炸效果傻唾。
- 音效類:主要播放音樂投慈。