先添上最終完成效果圖
Github代碼倉庫鏈接
https://github.com/happyte/plane, 這個是飛機大戰的代碼倉庫,不足之處希望大家指出。
基礎類的構建
導彈類
- 1.導彈是從飛機上發射的(無論是玩家的飛機還是敵機),導彈的位置需要根據飛機的位置確定,還需要根據是玩家飛機還是敵機確定導彈的圖片名和發射方向,因此需要傳入圖片名和位置參數。
pygame
框架加載圖片為圖像函數為:
pygame.image.load(image).convert()
傳入的參數是圖片的相對路徑
- 2.描繪出導彈的位置,導彈并且需要在初始化的
self.x
和self.y
基礎上移動位置,位置是在屏幕上描繪的,需要傳入屏幕參數。
pygame
顯示圖片函數為:screen.blit(self.image,(self.x,self.y)) pygame.display.update()
第一個參數為加載的圖像,第二個參數為左上角坐標。兩個函數是配合使用的,需要第二個函數去刷新界面。
## 飛機類
- 1.`Plane`類是接下來要創建的玩家類`Hero`和敵機類`Enemy`的基類。基類把兩者共同的屬性和方法定義出來,方便子類繼承。飛機要發射導彈,有一定的發射間隔,因此定義一個對象屬性`self.bulletSleepTime`。還需要一個列表存儲導彈,定義一個對象屬性為空列表`self.bulletList`。

`time.time()`可以用來確定當前時間,按照一定的格式可以轉換
- 2.在初始化的時候我們定義了導彈的發射間隔時間,大于間隔時間的話我們就往定義的列表中添加導彈對象,因為我現在只想讓玩家飛機發射子彈,因此初始化導彈對象特意往`self.x`加了`36(是玩家飛機72x72圖片寬度的一半)`,讓導彈在玩家飛機的正中間開始顯示。

- 3.描繪出飛機的位置

# 繼承類的構建
##玩家飛機類
- 1.在飛機基類中我們定義了一些共同的對象屬性,不同的對象屬性有圖像和原始位置,而且玩家飛機類對象還想擁有基類對象的屬性,所以需要調用`Plane.__init__(self)`函數,通過這個函數就擁有了`Plane`基類的對象屬性`bulletSleepTime`、`lastShootTime`、`bulletList`。

- 2.玩家飛機通過鍵盤的上下左右控制飛機的位置

##敵人飛機類
- 1.敵人飛機類中還多了速度對象屬性,考慮到隨著游戲難度的增加,敵人飛機速度越來越快,這個參數需要外界傳入。而且敵人飛機有小中大三種類型,是隨機的,起始的位置`x`軸也是隨機的,`y`軸固定從最上方開始。

用到了隨機數函數,需要導入`random`模塊
```objc
random.randint(1,3)
其中用到了super(Enemy,self).__init__()
與玩家類中的Plane.__init__(self)
效果是相同的。direction
對象屬性可以忽略,現在沒有用到。
- 2.敵人的飛機不斷往下掉,改變
self.y
,其實不用判斷,direction
沒有用到
游戲初始化類(封裝功能)
- 1.
GameInit
類創建了幾個類屬性,g_enemyList=[]
列表用于存儲敵人飛機對象,初始化玩家對象hero=object
,object
是元類,和用于統計玩家分數的屬性score
。
- 2.接下來定義了幾個類方法和靜態方法,用于封裝功能,在主函數里調用的都是這些類方法和靜態方法
-
往敵機列表中添加敵機對象,忽略下我的代碼英語好像打錯了
-
創建玩家飛機對象
-
游戲初始化
-
玩家飛機對象處理鍵盤操作,在玩家飛機類中已經定義了鍵盤處理函數,這里再封裝一層
-
更新敵人飛機位置,敵人飛機對象都在
g_enemyList
列表中
-
有3種類型的對象需要描繪,玩家飛機對象,敵人飛機對象和導彈,這個函數就是用來描繪這些對象,其中導彈和敵機需要判斷哪些對象超出屏幕從列表中刪除,這里用了
del
函數,記錄下索引值并從列表中刪除,同樣也可以用pop
函數,這里的j
為索引值
-
玩家飛機對象發射子彈,同時也要判斷打中了敵機就讓敵機對象和和子彈對象同時從列表中刪除。通過
pygame.Rect(self.image.get_rect())
獲得矩形的值,但是只獲得了圖像的width
和height
兩個屬性,前兩個屬性left
和top
都為0,因此還需要設置這兩個屬性,然后通過collidetect
判斷兩個矩形是否有相交處,其中索引值enemyIndex
和bulletIndex
需要仔細分析下
-
判斷玩家飛機是否與敵機相撞判斷游戲是否結束
- 3.幾個靜態方法,靜態方法不需要
cls
這個參數,通過類和實例都可以調用
-
退出整個程序
-
進入游戲后可以按
space
鍵停止游戲,其實就是就是個死循壞,按鍵按下后跳出函數
-
游戲開始后和結束后把分數顯示出來,第一個參數是分數,第二個參數是通過
pygame
的字體庫創建出來的,例如font = pygame.font.SysFont(None,64)
,參數分別為字體樣式和大小,可以選擇字體樣式例如arial
、simsun(宋體)
,第三個參數是屏幕,第四和第五個參數是字體顯示的left
和top
值。
主函數
- 1.運行一個模塊,有
if __name__ == 'main':
標識,會直接運行里面的代碼。第一步初始化pygame
庫,調用pygame.init()
,第二步創建一個窗口與背景圖片一樣大:screen = pygame.display.set_mode((ScreenWidth,ScreenHeight),0,32)
,然后可以設置窗口標題:pygame.display.set_caption('飛機大戰')
,第三步做一些初始化常量設置。其中紀錄了游戲開始的時間,因為按照我的思想游戲開始后難度會逐漸增加,我是通過時間來增加難度的
啟動時顯示start圖片,直到Enter
鍵按下才進入游戲 - 2.進入
while
循壞后,調用游戲初始化類封裝好的函數,通過時間間隔interval
選定游戲困難模式,通過改變敵機刷新的時間和敵機的速度增加難度,游戲結束后,再次按下Enter
按鍵退出程序。這里存在一個bug
,一旦游戲進行過程中按下Space
暫停游戲,interval
時間間隔仍然再計算(按道理應該讓時間暫停),再次按下Space
恢復游戲后,當前模式設定時間減少了或者進入更困難模式了。
總結
- 1.我用的版本是
python3.5
,不知道為什么無法導入音樂,提示我打不開音樂文件,目前還沒試過其它版本,猜測是否是因為版本的原因 - 2.接下來修復
bug
,目前完成了基本功能,下一步加入敵機爆炸效果和大型敵機是需要好幾發子彈才能擊毀 - 3.在運行程序前安裝
pygame
庫,我是在windows電腦上寫的,可以用pip list
查看安裝了哪些三方庫