杜蘭 陳琳琳 祎神靜


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