python 之路,200行Python代码写了个打飞机游戏!
先看一下項目結構
?
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | """ PlayPlane/ |-- bin/ |?? |-- main.py???????? 程序運行主體程序 |-- config/ |?? |-- settings.py???? 程序配置(例如: 游戲背景音樂的加載等) |-- material??????????? 程序素材放置(打飛機游戲素材放置) ????|-- ... |-- src/??????????????? 程序主體模塊存放 |?? |-- __init__.py |?? |-- bullet.py?????? 我方飛機發射子彈實現代碼存放 |?? |-- enemy.py??????? 敵方飛機實現代碼存放 |?? |-- plane.py??????? 我方飛機實現代碼存放 |-- manage.py?????????? 程序啟動文件 |-- README.md?????????? """ |
?
再曬下項目成果圖
實現步驟
一、首先在 config/settings.py 中進行以下功能的實現
- 游戲初始化
- 游戲混音器初始化
- 背景音樂初始化
- 我方飛機掛了音樂
- 敵方飛機掛了音樂
- 子彈發射音樂
+ View Code?
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #! /usr/bin/env python # -*- coding: utf-8 -*- ? importpygame ? pygame.init()? # 游戲初始化 pygame.mixer.init()? # 混音器初始化 ? # 游戲背景音樂 pygame.mixer.music.load("material/sound/game_music.wav") pygame.mixer.music.set_volume(0.2) ? # 子彈發射音樂 bullet_sound =pygame.mixer.Sound("material/sound/bullet.wav") bullet_sound.set_volume(0.2) ? # 我方飛機掛了的音樂 me_down_sound =pygame.mixer.Sound("material/sound/game_over.wav") me_down_sound.set_volume(0.2) ? # 敵方飛機掛了的音樂 enemy1_down_sound =pygame.mixer.Sound("material/sound/enemy1_down.wav") enemy1_down_sound.set_volume(0.2) ? config/settings.py |
?
注:游戲素材滑動到文章底部點擊鏈接即可下載
?
二、小試牛刀
飛機和子彈都是可移動的,那么怎么實現讓它們動起來呢(我方飛機可以玩家進行操控,敵機就是隨機性的出現,子彈暫由我方飛機發射)。
在Pygame中,所有移動對象都可看做是一個精靈(sprite),精靈之間能夠進行相互的交互通信,例如如何讓碰撞檢測更加精準等等。
那么先讓我們先在屏幕上制作一個游戲板,根據 settings.py 配置,并讓它有聲音播放,首先我們在 bin/main.py 中這么寫:
我們可以直接運行它,那么我們會看到以下畫面,并且還會有激情的聲音吆!!!但是我們要將文件配置為絕對路徑才可以運行,因為剛剛在settings中的加載的音樂文件為相對路徑。
+ View Code?
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #! /usr/bin/env python # -*- coding: utf-8 -*- ? importsys ? fromconfig.settings import* ? ? bg_size =480, 852? # 初始化游戲背景大小(寬, 高) screen =pygame.display.set_mode(bg_size)? # 設置背景對話框 pygame.display.set_caption("飛機大戰")? # 設置標題 ? background =pygame.image.load(os.path.join(BASE_DIR, "material/image/background.png"))? # 加載背景圖片,并設置為不透明 ? ? defmain(): ????pygame.mixer.music.play(loops=-1)? # loops 對應的值為 -1 則音樂會無限循環播放 ? ????whileTrue: ????????# 繪制背景圖 ????????screen.blit(background, (0, 0)) ? ????????# 響應用戶的操作(一定要有響應的用戶操作) ????????forevent inpygame.event.get(): ????????????ifevent.type==12:? # 如果用戶按下屏幕上的關閉按鈕,觸發QUIT事件,程序退出 ????????????????pygame.quit() ????????????????sys.exit() ? ????????# 再而我們將背景圖像并輸出到屏幕上面 ????????pygame.display.flip() ? if__name__ =='__main__': ????main() |
?
接下來呢,我們將要制作我方飛機,敵方飛機和子彈如何讓它們展示在游戲畫板上,繼而讓它們變得可移動起來,請看代碼實現方案...
從游戲畫板上添加飛機,首先我們應怎樣在屏幕上輸出飛機???
上述講過,pygame中的 sprite(精靈)可使一張圖片或者一個靜態物體動起來,那么制作飛機需要考慮并做些什么呢?
那么如何實現以上的功能呢?接下來結合上述的示例代碼我們先將我方飛機繪制到畫板上方,并且我們通過按鍵 J 判定我方飛機的存活狀態為死亡,繪制飛機的死亡畫面并重置飛機
+ View Code?
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | """ ????創建飛機 ????在pygame中, 所有可移動的對象均叫可看作一個精靈(sprite) ????該類并實現了碰撞方法 spritecollide ? ????我方飛機和敵方飛機指定掩膜屬性以及生存狀態標志位 添加 self.mask 屬性(可以實現更精準的碰撞效果) """ ? # 倒入精靈模塊, 使飛機可以動起來 importpygame ? ? classOurPlane(pygame.sprite.Sprite): ? ????def__init__(self, bg_size): ????????super(OurPlane, self).__init__() ????????# 確定我方飛機背景圖(有倆張,可以讓它們不停的切換,形成動態效果) ????????self.image_one =pygame.image.load("material/image/hero1.png") ????????self.image_two =pygame.image.load("material/image/hero2.png") ????????# 獲取我方飛機的位置 ????????self.rect =self.image_one.get_rect() ????????# 本地化背景圖片的尺寸 ????????self.width, self.height =bg_size[0], bg_size[1] ????????# 獲取飛機圖像的掩膜用以更加精確的碰撞檢測 ????????self.mask =pygame.mask.from_surface(self.image_one) ????????# 定義飛機初始化位置,底部預留60像素 ????????self.rect.left, self.rect.top =(self.width -self.rect.width) //2, (self.height -self.rect.height -60) ????????# 設置飛機移動速度 ????????self.speed =10 ????????# 設置飛機存活狀態(True為存活, False為死亡) ????????self.active =True ????????# 加載飛機損毀圖片 ????????self.destroy_images =[] ????????self.destroy_images.extend( ????????????[ ????????????????pygame.image.load("material/image/hero_blowup_n1.png"), ????????????????pygame.image.load("material/image/hero_blowup_n2.png"), ????????????????pygame.image.load("material/image/hero_blowup_n3.png"), ????????????????pygame.image.load("material/image/hero_blowup_n4.png") ????????????] ????????) ? ????defmove_up(self): ????????""" ????????飛機向上移動的操作函數,其余移動函數方法類似 ????????""" ????????ifself.rect.top > 0:? # 如果飛機尚未移動出背景區域 ????????????self.rect.top -=self.speed ????????else:? # 若即將移動出背景區域,則及時糾正為背景邊緣位置 ????????????self.rect.top =0 ? ????defmove_down(self): ????????""" ????????飛機向下移動 ????????""" ????????ifself.rect.bottom < self.height -60: ????????????self.rect.top +=self.speed ????????else: ????????????self.rect.bottom =self.height -60 ? ????defmove_left(self): ????????""" ????????飛機向左移動 ????????""" ????????ifself.rect.left > 0: ????????????self.rect.left -=self.speed ????????else: ????????????self.rect.left =0 ? ????defmove_right(self): ????????""" ????????飛機向右移動 ????????""" ????????ifself.rect.right < self.width: ????????????self.rect.right +=self.speed ????????else: ????????????self.rect.right =self.width ? ????defreset(self): ????????# 初始化飛機(飛機掛了, 初始化到初始位置) ????????self.rect.left, self.rect.top =(self.width -self.rect.width) //2, (self.height -self.rect.height -60) ????????# 重置飛機的存活狀態 ????????self.active =True |
上面的代碼寫了一個 我們的飛機 (OurPlane) 類,它初始化了一些屬性以及 上下左右 移動的方法和重置方法,接下來將要運用它展示到游戲畫板上面
由于飛機是一直存在的,接下我們主程序 main 下面的死循環中這樣寫
?
def main():pygame.mixer.music.play(loops=-1) # loops 對應的值為 -1 則音樂會無限循環播放our_plane = OurPlane(bg_size) # 初始化switch_image = False # 定義飛機的切圖效果標識while True:# 繪制背景圖screen.blit(background, (0, 0))# 飛機狀態是存活if our_plane.active:if switch_image:screen.blit(our_plane.image_one, our_plane.rect)else:screen.blit(our_plane.image_two, our_plane.rect)switch_image = not switch_image # 讓切圖狀態不停的變換else:pass# 響應用戶的操作(一定要有響應的用戶操作)for event in pygame.event.get():if event.type == 12: # 如果用戶按下屏幕上的關閉按鈕,觸發QUIT事件,程序退出pygame.quit()sys.exit()# 再而我們將背景圖像并輸出到屏幕上面pygame.display.flip()if __name__ == '__main__':main()1.在屏幕上繪制飛機
def main():pygame.mixer.music.play(loops=-1) # loops 對應的值為 -1 則音樂會無限循環播放our_plane = OurPlane(bg_size) # 初始化switch_image = False # 定義飛機的切圖效果標識while True:# 繪制背景圖screen.blit(background, (0, 0))# 飛機狀態是存活if our_plane.active:if switch_image:screen.blit(our_plane.image_one, our_plane.rect)else:screen.blit(our_plane.image_two, our_plane.rect)switch_image = not switch_image # 讓切圖狀態不停的變換else:pass# 獲得用戶所有的鍵盤輸入序列(如果用戶通過鍵盤發出“向上”的指令,其他類似)key_pressed = pygame.key.get_pressed()if key_pressed[K_w] or key_pressed[K_UP]:our_plane.move_up()if key_pressed[K_s] or key_pressed[K_DOWN]:our_plane.move_down()if key_pressed[K_a] or key_pressed[K_LEFT]:our_plane.move_left()if key_pressed[K_d] or key_pressed[K_RIGHT]:our_plane.move_right()# 響應用戶的操作(一定要有響應的用戶操作)for event in pygame.event.get():if event.type == 12: # 如果用戶按下屏幕上的關閉按鈕,觸發QUIT事件,程序退出pygame.quit()sys.exit()# 再而我們將背景圖像并輸出到屏幕上面pygame.display.flip()if __name__ == '__main__':main()2.讓飛機上下左右動起來
def main():pygame.mixer.music.play(loops=-1) # loops 對應的值為 -1 則音樂會無限循環播放our_plane = OurPlane(bg_size) # 初始化switch_image = False # 定義飛機的切圖效果標識our_plane_destroy_index = 0while True:# 繪制背景圖screen.blit(background, (0, 0))# 飛機狀態是存活(如果按鍵 為 J, 讓飛機死亡并繪制爆炸效果)if our_plane.active:if switch_image:screen.blit(our_plane.image_one, our_plane.rect)else:screen.blit(our_plane.image_two, our_plane.rect)switch_image = not switch_image # 讓切圖狀態不停的變換else:"""飛機死亡也是進行按順序的圖片切換, 那么在死循環之外定義索引"""me_destroy_index = (our_plane_destroy_index + 1) % 4if me_destroy_index == 1:me_down_sound.play() # 爆炸聲音效果our_plane.reset() # 初始化飛機if our_plane_destroy_index >= len(our_plane.destroy_images):our_plane_destroy_index = 0else:screen.blit(our_plane.destroy_images[our_plane_destroy_index], our_plane.rect)our_plane_destroy_index += 1# 獲得用戶所有的鍵盤輸入序列(如果用戶通過鍵盤發出“向上”的指令,其他類似)key_pressed = pygame.key.get_pressed()if key_pressed[K_w] or key_pressed[K_UP]:our_plane.move_up()if key_pressed[K_s] or key_pressed[K_DOWN]:our_plane.move_down()if key_pressed[K_a] or key_pressed[K_LEFT]:our_plane.move_left()if key_pressed[K_d] or key_pressed[K_RIGHT]:our_plane.move_right()# 按鍵為 j 飛機更改存活標識if key_pressed[K_j]:our_plane.active = False# 響應用戶的操作(一定要有響應的用戶操作)for event in pygame.event.get():if event.type == 12: # 如果用戶按下屏幕上的關閉按鈕,觸發QUIT事件,程序退出pygame.quit()sys.exit()# 再而我們將背景圖像并輸出到屏幕上面pygame.display.flip()3.按鍵為 j 繪制飛機的死亡狀態
那么上述的功能都已經實現了,接下來就開始真正的"打飛機"
三、接下來可以制作我方飛機,敵方戰機,子彈等,這些功能均在 src/ 目錄下實現
- 我方飛機根據按鍵上下左右進行移動,初始化位置,噴氣式圖片加載切換及重置效果等
src/plane.py
- 敵方飛機隨機移動出現及重置(制作出我方飛機之后,敵機和子彈其實都是大同小異的)
- #! /usr/bin/env python # -*- coding: utf-8 -*-"""定義敵機 """from random import randintimport pygameclass SmallEnemy(pygame.sprite.Sprite):"""定義小飛機敵人"""def __init__(self, bg_size):super(SmallEnemy, self).__init__()self.image = pygame.image.load("material/image/enemy1.png")self.rect = self.image.get_rect()self.width, self.height = bg_size[0], bg_size[1]self.mask = pygame.mask.from_surface(self.image) # 獲取飛機圖像的掩膜用以更加精確的碰撞檢測self.speed = 2# 定義敵機出現的位置, 保證敵機不會在程序已開始就立即出現self.rect.left, self.rect.top = (randint(0, self.width - self.rect.width), randint(-5 * self.rect.height, -5),)self.active = True# 加載飛機損毀圖片self.destroy_images = []self.destroy_images.extend([pygame.image.load("material/image/enemy1_down1.png"),pygame.image.load("material/image/enemy1_down2.png"),pygame.image.load("material/image/enemy1_down3.png"),pygame.image.load("material/image/enemy1_down4.png")])def move(self):"""定義敵機的移動函數:return:"""if self.rect.top < self.height:self.rect.top += self.speedelse:self.reset()def reset(self):"""當敵機向下移動出屏幕時, 以及敵機死亡:return:"""self.rect.left, self.rect.top = (randint(0, self.width - self.rect.width), randint(-5 * self.rect.height, 0))self.active = True src/enemy.py
- 子彈按照我方飛機正中上方發射及頻率調控,重置
src/bullet.py
?
在上面的內容中,使用面向對象的形式制作了游戲中可移動的對象并繼承 pygame.sprite.Sprite?
四、然后在 bin/main.py 中進行主體功能的實現
- 初始化背景圖及大小
- 我方飛機移動及發射子彈
- 敵方飛機移動
- 我方飛機和敵方飛機碰撞檢測
- 鍵盤按鍵監測效果
- 我方飛機和敵方飛機掛了效果繪制
bin/main.py
如果大家對Python感興趣的話,可以加一下我們的學習交流摳摳群哦:649825285,免費領取一套學習資料和視頻課程喲~
五、暢汗淋漓,一氣呵成打飛機
?
| 1 2 3 4 5 6 7 8 9 | from bin.main import main ? ? if __name__ == '__main__': ????""" ????環境: python3 + pygame ????running 起來就可以打飛機了O(∩_∩)O~. ????""" ????main() |
最終效果!
?
總結
以上是生活随笔為你收集整理的python 之路,200行Python代码写了个打飞机游戏!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 无代码时代来临,程序员如何保住饭碗?赶紧
- 下一篇: 初学者是学习 C 语言还是 C++ 好?