用Python實現(xiàn)飛機大戰(zhàn)小游戲的完整代碼
飛機大戰(zhàn)是個什么樣的小游戲呢?
首先我們需要有一個自己的飛機,它可以在畫面上進行上下左右移動,我們通過方向鍵來控制它的移動,我們的飛機要發(fā)射子彈,用來擊打敵機,我們用空格鍵來控制子彈的發(fā)射
然后需要設(shè)置敵機,隨機出現(xiàn)在畫面上,以一定的速度向下移動 敵機和我們自己的飛機相撞時游戲結(jié)束
游戲結(jié)束時統(tǒng)計得分,擊落一只敵機得10分
至此,我們一個飛機大戰(zhàn)的小游戲就設(shè)計完成了!那么,要如何實現(xiàn)呢?
上完整代碼:
# air_shoot.py
# 飛機大戰(zhàn)小游戲
import pygame
import random
import sys
# 初始化 Pygame
pygame.init()
# 屏幕大小
WIDTH, HEIGHT = 480, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("plane war")
# 顏色
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
# 時鐘(控制幀率)
clock = pygame.time.Clock()
# 字體
font = pygame.font.SysFont("simhei", 32) # 如果報錯,改為 None 或 "Arial"
small_font = pygame.font.SysFont("simhei", 24)
# 玩家飛機
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((50, 40))
self.image.fill(GREEN)
self.rect = self.image.get_rect()
self.rect.centerx = WIDTH // 2
self.rect.bottom = HEIGHT - 10
self.speed = 5
def update(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and self.rect.left > 0:
self.rect.x -= self.speed
if keys[pygame.K_RIGHT] and self.rect.right < WIDTH:
self.rect.x += self.speed
if keys[pygame.K_UP] and self.rect.top > 0:
self.rect.y -= self.speed
if keys[pygame.K_DOWN] and self.rect.bottom < HEIGHT:
self.rect.y += self.speed
def shoot(self):
bullet = Bullet(self.rect.centerx, self.rect.top)
all_sprites.add(bullet)
bullets.add(bullet)
# 敵機
class Enemy(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((40, 30))
self.image.fill(RED)
self.rect = self.image.get_rect()
self.rect.x = random.randint(0, WIDTH - self.rect.width)
self.rect.y = random.randint(-100, -40)
self.speed = random.randint(2, 5)
def update(self):
self.rect.y += self.speed
if self.rect.top > HEIGHT:
self.kill() # 移出屏幕后刪除
# 子彈
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pygame.Surface((5, 10))
self.image.fill(WHITE)
self.rect = self.image.get_rect()
self.rect.centerx = x
self.rect.bottom = y
self.speed = -10
def update(self):
self.rect.y += self.speed
if self.rect.bottom < 0:
self.kill()
# 顯示文字
def draw_text(surf, text, font, x, y, color=WHITE):
img = font.render(text, True, color)
rect = img.get_rect()
rect.midtop = (x, y)
surf.blit(img, rect)
# 游戲結(jié)束畫面
def show_game_over(score):
screen.fill(BLACK)
draw_text(screen, "GAME OVER", font, WIDTH//2, HEIGHT//2 - 50, RED)
draw_text(screen, f"SCORE: {score}", small_font, WIDTH//2, HEIGHT//2)
draw_text(screen, "press R restart, Q quit", small_font, WIDTH//2, HEIGHT//2 + 50)
pygame.display.flip()
waiting = True
while waiting:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_r:
waiting = False
if event.key == pygame.K_q:
pygame.quit()
sys.exit()
# 主游戲函數(shù)
def game():
global all_sprites, bullets, enemies
all_sprites = pygame.sprite.Group()
bullets = pygame.sprite.Group()
enemies = pygame.sprite.Group()
player = Player()
all_sprites.add(player)
score = 0
enemy_spawn_rate = 30 # 幀數(shù)(越小越密集)
running = True
while running:
clock.tick(60)
current_frame = pygame.time.get_ticks() // 1000 * 60 # 當前幀數(shù)(粗略)
# 事件處理
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# 按鍵射擊(長按連續(xù)發(fā)射)
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE]:
if len(bullets) < 5: # 限制子彈數(shù)量
player.shoot()
# 生成敵機
if random.randint(1, enemy_spawn_rate) == 1:
enemy = Enemy()
all_sprites.add(enemy)
enemies.add(enemy)
# 更新所有精靈
all_sprites.update()
# 子彈擊中敵機
hits = pygame.sprite.groupcollide(enemies, bullets, True, True)
for hit in hits:
score += 10
# 玩家與敵機碰撞
if pygame.sprite.spritecollide(player, enemies, False):
running = False
# 繪制
screen.fill(BLACK)
all_sprites.draw(screen)
draw_text(screen, f"score: {score}", small_font, 60, 10)
pygame.display.flip()
# 游戲結(jié)束
show_game_over(score)
# 主循環(huán)(支持重玩)
while True:
game()
游戲整體結(jié)構(gòu)
這個游戲使用了 Pygame 框架 和 面向?qū)ο缶幊蹋∣OP) 的方式來組織代碼。主要分為以下幾個部分:
- 初始化設(shè)置
- 定義游戲?qū)ο箢悾ㄍ婕?、敵機、子彈)
- 游戲主循環(huán)
- 碰撞檢測與得分
- 游戲結(jié)束界面
- 支持重玩機制
第一部分:導(dǎo)入模塊和初始化
import pygame import random import sys
pygame:核心游戲庫。random:用于生成隨機位置、速度等。sys:用于安全退出程序。
pygame.init()
初始化所有 Pygame 的模塊(如聲音、顯示、字體等),這是使用 Pygame 的第一步。
WIDTH, HEIGHT = 480, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("飛機大戰(zhàn)")
- 設(shè)置窗口大小為 480×600 像素。
- 創(chuàng)建一個顯示窗口,并設(shè)置標題為“飛機大戰(zhàn)”。
WHITE = (255, 255, 255) BLACK = (0, 0, 0) RED = (255, 0, 0) GREEN = (0, 255, 0)
定義顏色常量。Pygame 中顏色用 RGB 元組表示:
(255, 255, 255)是白色(0, 0, 0)是黑色(255, 0, 0)是紅色(敵機)(0, 255, 0)是綠色(玩家)
clock = pygame.time.Clock()
創(chuàng)建一個時鐘對象,用來控制游戲幀率(FPS),防止運行過快或過慢。
font = pygame.font.SysFont("simhei", 32)
small_font = pygame.font.SysFont("simhei", 24)
創(chuàng)建字體對象,用于在屏幕上繪制文字。
"simhei"是黑體,支持中文。- 如果系統(tǒng)沒有這個字體,可以用
'Arial'或None替代。
第二部分:定義游戲角色類
1. 玩家飛機類Player
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((50, 40))
self.image.fill(GREEN)
self.rect = self.image.get_rect()
self.rect.centerx = WIDTH // 2
self.rect.bottom = HEIGHT - 10
self.speed = 5
- 繼承自
pygame.sprite.Sprite—— 這是 Pygame 中所有可移動對象的基礎(chǔ)類。 image:角色的外觀,這里是一個綠色矩形(50寬 × 40高)。rect:角色的位置和邊界框。- 初始位置:水平居中,底部距離屏幕底邊 10 像素。
speed:移動速度。
def update(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and self.rect.left > 0:
self.rect.x -= self.speed
if keys[pygame.K_RIGHT] and self.rect.right < WIDTH:
self.rect.x += self.speed
if keys[pygame.K_UP] and self.rect.top > 0:
self.rect.y -= self.speed
if keys[pygame.K_DOWN] and self.rect.bottom < HEIGHT:
self.rect.y += self.speed
每一幀調(diào)用一次
update()方法:
- 獲取當前按下的按鍵狀態(tài)。
- 控制方向鍵移動。
- 加入邊界判斷,不讓飛機飛出窗口。
def shoot(self):
bullet = Bullet(self.rect.centerx, self.rect.top)
all_sprites.add(bullet)
bullets.add(bullet)
發(fā)射子彈的方法:
- 在飛機頂部中心創(chuàng)建一顆子彈。
- 把它加入總精靈組
all_sprites和子彈組bullets,以便更新和繪制。
2. 敵機類Enemy
class Enemy(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((40, 30))
self.image.fill(RED)
self.rect = self.image.get_rect()
self.rect.x = random.randint(0, WIDTH - self.rect.width)
self.rect.y = random.randint(-100, -40)
self.speed = random.randint(2, 5)
- 紅色矩形代表敵機。
- 出現(xiàn)在屏幕上方(y 為負值),從不同 x 位置隨機出現(xiàn)。
- 下落速度隨機(2~5像素/幀)。
def update(self):
self.rect.y += self.speed
if self.rect.top > HEIGHT:
self.kill() # 移出屏幕后刪除
敵機持續(xù)下落,一旦完全移出屏幕底部就自動銷毀(
kill()),避免內(nèi)存泄漏。
3. 子彈類Bullet
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pygame.Surface((5, 10))
self.image.fill(WHITE)
self.rect = self.image.get_rect()
self.rect.centerx = x
self.rect.bottom = y
self.speed = -10 # 負數(shù)表示向上飛
- 白色小矩形表示子彈。
- 從玩家飛機頂部發(fā)射。
- 向上飛行(
speed = -10)。
def update(self):
self.rect.y += self.speed
if self.rect.bottom < 0:
self.kill() # 子彈飛出屏幕頂端就銷毀
第三部分:輔助函數(shù)
顯示文字函數(shù)
def draw_text(surf, text, font, x, y, color=WHITE):
img = font.render(text, True, color)
rect = img.get_rect()
rect.midtop = (x, y)
surf.blit(img, rect)
封裝了一個通用的文字繪制函數(shù):
surf:要畫在哪(通常是screen)text:要顯示的文字font:字體對象(x, y):文字左上角坐標blit():把文字圖像畫到屏幕上
游戲結(jié)束畫面
def show_game_over(score):
screen.fill(BLACK)
draw_text(screen, "游戲結(jié)束", font, WIDTH//2, HEIGHT//2 - 50, RED)
draw_text(screen, f"得分: {score}", small_font, WIDTH//2, HEIGHT//2)
draw_text(screen, "按 R 重新開始,Q 退出", small_font, WIDTH//2, HEIGHT//2 + 50)
pygame.display.flip()
waiting = True
while waiting:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_r:
waiting = False
if event.key == pygame.K_q:
pygame.quit()
sys.exit()
顯示“游戲結(jié)束”界面并等待用戶選擇:
- 填黑背景,顯示得分。
- 提示按 R 重玩,Q 退出。
- 使用一個循環(huán)等待輸入,直到用戶決定。
第四部分:主游戲函數(shù)game()
def game():
global all_sprites, bullets, enemies
all_sprites = pygame.sprite.Group()
bullets = pygame.sprite.Group()
enemies = pygame.sprite.Group()
player = Player()
all_sprites.add(player)
score = 0
enemy_spawn_rate = 30 # 每30幀左右生成一架敵機
running = True
初始化游戲狀態(tài):
- 創(chuàng)建三個精靈組:
all_sprites:所有要繪制和更新的對象bullets:所有子彈enemies:所有敵機
- 添加玩家
- 得分從 0 開始
while running:
clock.tick(60) # 鎖定60 FPS
# 事件處理
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
主循環(huán)每秒運行約 60 次(由
clock.tick(60)控制)。
處理退出事件。
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE]:
if len(bullets) < 5: # 限制最多5發(fā)子彈
player.shoot()
檢測是否按下空格鍵,如果是且子彈不多于5個,則發(fā)射。
# 生成敵機
if random.randint(1, enemy_spawn_rate) == 1:
enemy = Enemy()
all_sprites.add(enemy)
enemies.add(enemy)
隨機生成敵機(大約每 30 幀生成一架)。
all_sprites.update()
更新所有精靈的位置(包括玩家、敵機、子彈)。
# 子彈擊中敵機
hits = pygame.sprite.groupcollide(enemies, bullets, True, True)
for hit in hits:
score += 10
groupcollide()自動檢測兩組精靈之間的碰撞:
- 子彈打中敵機 → 雙方都銷毀(
True, True) - 每消滅一個敵機加 10 分
# 玩家與敵機碰撞
if pygame.sprite.spritecollide(player, enemies, False):
running = False
如果玩家碰到任何敵機(即使只是擦邊),游戲結(jié)束。
# 繪制畫面
screen.fill(BLACK)
all_sprites.draw(screen)
draw_text(screen, f"得分: {score}", small_font, 60, 10)
pygame.display.flip()
清屏 → 畫所有精靈 → 顯示得分 → 刷新屏幕
show_game_over(score) # 游戲結(jié)束后顯示結(jié)束畫面
第五部分:支持重復(fù)游戲
while True:
game()
主循環(huán)外再套一層
while True,這樣每次游戲結(jié)束后都可以重新開始。
總結(jié):游戲運行流程圖
開始游戲 ↓ 初始化 Pygame 和變量 ↓ 進入 game() 函數(shù) ↓ 創(chuàng)建玩家和精靈組 ↓ 主循環(huán): → 處理事件(退出、按鍵) → 玩家移動/射擊 → 隨機生成敵機 → 更新所有精靈位置 → 檢測碰撞(子彈打敵機、玩家撞敵機) → 繪制畫面和得分 ↓ 玩家被撞 → 結(jié)束主循環(huán) ↓ 調(diào)用 show_game_over() ↓ 等待用戶按 R 或 Q → 按 R:回到 game() 重新開始 → 按 Q:退出程序
后續(xù)擴展建議
你可以基于這個框架繼續(xù)添加功能:
| 功能 | 實現(xiàn)思路 |
|---|---|
| 添加音效 | 使用 pygame.mixer.Sound() 播放射擊、爆炸音效 |
| 使用圖片代替方塊 | pygame.image.load("player.png") |
| 添加爆炸動畫 | 碰撞時播放一系列圖片 |
| 生命值系統(tǒng) | 玩家可承受多次撞擊 |
| 道具掉落 | 敵機死亡時隨機掉落加速、多子彈等道具 |
到此這篇關(guān)于用Python實現(xiàn)飛機大戰(zhàn)小游戲的文章就介紹到這了,更多相關(guān)Python飛機大戰(zhàn)小游戲內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python經(jīng)典趣味24點游戲程序設(shè)計
這篇文章主要介紹了python經(jīng)典趣味24點游戲程序設(shè)計,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧2019-07-07
Python 多線程搜索txt文件的內(nèi)容,并寫入搜到的內(nèi)容(Lock)方法
今天小編就為大家分享一篇Python 多線程搜索txt文件的內(nèi)容,并寫入搜到的內(nèi)容(Lock)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-08-08
使用selenium模擬登錄解決滑塊驗證問題的實現(xiàn)
這篇文章主要介紹了使用selenium模擬登錄解決滑塊驗證問題的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧2019-05-05
python免殺技術(shù)shellcode的加載與執(zhí)行
本文主要介紹了python免殺技術(shù)shellcode的加載與執(zhí)行,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧2023-04-04

