杜蘭 陳琳琳 祎神靜
摘要 本文通過(guò)開(kāi)發(fā)經(jīng)典的壁球游戲展示了基于Pygame開(kāi)發(fā)壁球的基本過(guò)程,重點(diǎn)介紹了壁球游戲的需求分析、核心算法和性能調(diào)優(yōu)。
【關(guān)鍵詞】Pygame 飛機(jī)射擊 游戲開(kāi)發(fā)
1 概述
游戲正逐漸成為人們?nèi)粘蕵?lè)方式,游戲開(kāi)發(fā)也成為軟件開(kāi)發(fā)領(lǐng)域的重要分支。Pygame是Python的一個(gè)第三方庫(kù),搭載了基于OpenGL的圖形庫(kù)和優(yōu)質(zhì)的音頻庫(kù),可以快速上手制作2D游戲的原型。Pygame的API比較偏底層,開(kāi)發(fā)人員在編程時(shí)具有很大的自由度,同時(shí)具有了很強(qiáng)的可定制性。
2 需求分析
(1)游戲窗口內(nèi)分為兩個(gè)區(qū)域:游戲區(qū)域和計(jì)分板。
(2)在游戲區(qū)域里有一個(gè)深紅色的小球在運(yùn)動(dòng),小球撞擊到游戲區(qū)域左、右兩側(cè)的邊界時(shí)回彈,如果擊中上邊界則會(huì)向下回彈,玩家和AI輪流進(jìn)行擊球,開(kāi)局由玩家發(fā)球。
(3)玩家通過(guò)鼠標(biāo)來(lái)左右移動(dòng)球拍,并且在小球靠近時(shí)按下鼠標(biāo)左鍵,進(jìn)行擊球,成功擊球之后小球會(huì)向上回彈,而AI則會(huì)自動(dòng)跟隨小球,進(jìn)行擊球。游戲中設(shè)置AI擊球失敗的概率。如果向下運(yùn)動(dòng)的過(guò)程中小球的高度低于某個(gè)閾值時(shí),則本局游戲結(jié)束,如果是玩家擊球失敗則AI得分,否則,玩家得分。
(4)率先贏取3分的選手即為整場(chǎng)比賽的獲勝者。單局勝利累計(jì)分?jǐn)?shù),全局結(jié)束顯示“You Win”或者“You Lose”的字樣表示輸贏結(jié)果。
(5)游戲內(nèi)設(shè)有背景音樂(lè)以及擊球音效。
3 壁球游戲設(shè)計(jì)核心算法
3.1 小球的運(yùn)動(dòng)
用centerX表示圓心橫坐標(biāo),centerY表示圓心縱坐標(biāo),radius表示半徑。用velocityX來(lái)表示小球水平方向的速度,用velocityY來(lái)表示小球在垂直方向的速度。小球碰撞檢測(cè)的方法是檢測(cè)圓心的centerX到左側(cè)邊界的距離,如果這個(gè)距離小于小球的半徑,則說(shuō)明發(fā)生了碰撞,同時(shí)這里需要做一個(gè)修正,重置centerX的值,使得小球與游戲區(qū)域的左側(cè)邊界相切,從而避免了視覺(jué)上的穿越。同理,當(dāng)centerX到右側(cè)邊界的距離小于等于小球半徑時(shí),則說(shuō)明小球與右側(cè)的邊界發(fā)生了碰撞,此時(shí)更新velocityX并且重置centerX的值。對(duì)于上側(cè)邊界的檢測(cè)也是同理,不過(guò)這里處理的是y方向,如果centerY到上側(cè)邊界的距離小于等于小球的半徑則說(shuō)明小球與上側(cè)邊界發(fā)生了碰撞,更新velocityY并且重置centerY的值。部分代碼如下所示:
小球運(yùn)動(dòng)部分代碼如下所示:
ifself.centerX - selfradius<-0:
self.centerX - self.radius
self.velocityX= -self.velocityX
elifself.centerX+self.radius>-gameArea[2]: self.centerX - gameArea[2] - self.radius self.velocityX= -self.velocityX ifself.centerY - self.radius<-O: self.centerY - selfradius self.velocityY= -self.velocityY
3.2 玩家的擊球操作
本文把小球在擊球區(qū)域里等價(jià)于小球的圓心在擊球區(qū)域里。因?yàn)閾羟騾^(qū)域是一個(gè)矩形,因此這個(gè)問(wèn)題可以被建模成判斷一個(gè)點(diǎn)是否在一個(gè)矩形區(qū)域里的問(wèn)題。如圖1所示,在Pygame中,用(startX,startY, width,height)的4元組來(lái)表示一個(gè)矩形的位置與大小的信息,因此矩形的左上角的坐標(biāo)即為(startX,startY),矩形的右下角的坐標(biāo)即為(startX+width,startY+ height),要判斷一個(gè)點(diǎn)是否在這個(gè)矩形區(qū)域里,就可以轉(zhuǎn)換成下面的判斷。
startX≤pointX≤startX+width
startY≤pointY≤startY+height
其中(pointX,pointY)為需要判斷的點(diǎn)的坐標(biāo)。當(dāng)這個(gè)不等式組成立時(shí),可以判斷該點(diǎn)在矩形區(qū)域內(nèi),否則該點(diǎn)在矩形區(qū)域外側(cè)。
為了使游戲具有可玩性,擊球后需要更改的不只是小球的velocityY,還需要改變小球的velocityX。如果不加以改變的話(huà),則小球只會(huì)不斷的按照順時(shí)針或者逆時(shí)針的方向進(jìn)行運(yùn)動(dòng),這樣的設(shè)計(jì)會(huì)使得游戲的可玩性大大降低。因此,需要有一種策略來(lái)決定擊球之后velocityX的符號(hào)。通過(guò)描述擊球區(qū)域的元組,可以計(jì)算出中心點(diǎn)的橫坐標(biāo)middleX,如果小球的centerX小于middleX,則將velocityX的符號(hào)設(shè)置為負(fù)號(hào),否則設(shè)置為正號(hào)。這樣,玩家在擊球之后可以有一定的概率改變小球的運(yùn)動(dòng)方向,并且從而使得小球的運(yùn)動(dòng)軌跡具有多樣性,下一次擊球時(shí)合適的擊球區(qū)域也會(huì)隨之變化,這就增加了游戲的不確定性,進(jìn)一步增強(qiáng)了玩家與游戲之間的互動(dòng)和游戲本身的可玩性。部分代碼如下:
部分代碼如下:
ifselfcenterX
self.velocityX= -abs(self.velocityX)
else:
self.velociWX - abs(self.velocityX)
3.3 AI的擊球操作
本文采用了一個(gè)簡(jiǎn)單的思想:AI控制的球拍的橫向位置與小球保持同步,這樣每當(dāng)小球下落到AI的球拍的高度的時(shí)候,小球總能夠出現(xiàn)在AI的擊球區(qū)域里。這樣會(huì)產(chǎn)生一個(gè)問(wèn)題:AI必然可以l00%的擊中小球,則玩家永遠(yuǎn)不可能贏過(guò)AI!因此需要對(duì)這個(gè)簡(jiǎn)單的策略做出一些改進(jìn):設(shè)置一個(gè)(0,1)之間的閾值missRate,比如說(shuō)0.1,表示AI擊球失敗的概率,也就是說(shuō)每次擊球時(shí)AI都會(huì)有missRate的概率無(wú)法打中球,這樣玩家就會(huì)有機(jī)會(huì)贏過(guò)AI,最終獲勝。
部分代碼如下:
miss- random.random()
print(miss)
if miss >OpponentMissRate:
selfhitSound play()
pyganle tlme wait(lOO)
selfba11.hit(selfopponemHitArea)
direction=random.randomn
if direction<0 5:
selfbalI.velocityX=-selfball.velocityX
4 性能調(diào)優(yōu)
一款游戲要推廣的一個(gè)前提是在目標(biāo)機(jī)上能夠流暢運(yùn)行。因此在實(shí)現(xiàn)基本功能之后,要針對(duì)游戲本身的性能進(jìn)行一些優(yōu)化,在考慮到變量在內(nèi)存中的排列以及Python的GC機(jī)制的基礎(chǔ)上,要合理的管理游戲?qū)ο蠛妥兞?。?jīng)過(guò)了少許的性能調(diào)優(yōu)之后,軟件可以流暢的在絕大多數(shù)的學(xué)生筆記本電腦上以60FPS的幀頻運(yùn)行。
5 結(jié)束語(yǔ)
Pyganle可以大大的加快游戲開(kāi)發(fā)者的開(kāi)發(fā)速度,同時(shí)也避免了由于平臺(tái)不兼容而影響游戲開(kāi)發(fā)的進(jìn)程。本文重點(diǎn)討論了基于pygame的飛機(jī)射擊游戲的的核心算法以及游戲的性能調(diào)優(yōu)。
參考文獻(xiàn)
[1] SWEIGART A.Making Games with Pvthon&Pygame [M]. charles ton: CreateSpaceIndependent Publishing Platform, 2012.
[2]王攀拓.基于Python的Pygame框架研究[D].齊齊哈爾:齊齊哈爾大學(xué),2015.
[3]劉班.用Python語(yǔ)言開(kāi)發(fā)彈跳球游戲[J].電腦編程技巧與維護(hù),2014 (07):79-84.