欢迎光临
我们一直在努力

python小游戏实战:打造一款视觉精美的飞机大战

在这里插入图片描述

在这里插入图片描述

python小游戏实战:打造一款视觉精美的飞机大战

python小游戏实战:打造一款视觉精美的飞机大战,飞机大战作为经典的射击类小游戏,凭借简单的操作和紧张刺激的玩法,成为很多开发者入门游戏开发的首选案例。本次实战将使用 Python 的pygame库,从零开始打造一款画面精美、功能完整的飞机大战小游戏,涵盖窗口创建、角色绘制、碰撞检测、音效添加等核心知识点。即使是 Python 新手,也能通过本教程掌握 2D 小游戏开发的基本思路。

在这里插入图片描述

一、前言

    Python作为一门简洁、易读、功能强大的编程语言,其基础语法是入门学习的核心。掌握好基础语法,能为后续的编程实践打下坚实的基础。本文将全面讲解Python3的基础语法知识,适合编程初学者系统学习。Python以其简洁优雅的语法和强大的通用性,成为当今最受欢迎的编程语言。本专栏旨在系统性地带你从零基础入门到精通Python核心。无论你是零基础小白还是希望进阶的专业开发者,都将通过清晰的讲解、丰富的实例和实战项目,逐步掌握语法基础、核心数据结构、函数与模块、面向对象编程、文件处理、主流库应用(如数据分析、Web开发、自动化)以及面向对象高级特性,最终具备独立开发能力和解决复杂问题的思维,高效应对数据分析、人工智能、Web应用、自动化脚本等广泛领域的实际需求。

在这里插入图片描述


在这里插入图片描述

🥇 点击进入Python入门专栏,Python凭借简洁易读的语法,是零基础学习编程的理想选择。本专栏专为初学者设计,系统讲解Python核心基础:变量、数据类型、流程控制、函数、文件操作及常用库入门。通过清晰示例与实用小项目,助你快速掌握编程思维,打下坚实根基,迈出自动化办公、数据分析或Web开发的第一步。

🥇 点击进入Python小游戏实战专栏, 寓教于乐,用Python亲手打造经典小游戏!本专栏通过开发贪吃蛇、飞机大战、猜数字、简易版俄罗斯方块等趣味项目,在实践中掌握Python核心语法、面向对象编程、事件处理、图形界面(如Pygame)等关键技能,将枯燥的代码学习转化为可见的成果,让学习编程充满乐趣与成就感,快速提升实战能力。

🥇 点击进入Python小工具实战专栏,告别重复劳动,用Python打造效率神器!本专栏教你开发文件批量处理、自动邮件通知、简易爬虫、桌面提醒、密码生成器、天气查询等实用小工具。聚焦os、shutil、requests、smtplib、schedule等核心库,通过真实场景案例,快速掌握自动化脚本编写技巧,解放双手,显著提升工作与生活效率,让代码真正服务于你的日常。

🥇 点击进入Python爬虫实战专栏,解锁网络数据宝库!本专栏手把手教你使用Python核心库(如requests、BeautifulSoup、Scrapy)构建高效爬虫。从基础网页解析到动态页面抓取、数据存储(CSV/数据库)、反爬策略应对及IP代理使用,通过实战项目(如电商比价、新闻聚合、图片采集、舆情监控),掌握合法合规获取并利用网络数据的核心技能,让数据成为你的超能力。

🥇 点击进入Python项目实战专栏,告别碎片化学习,挑战真实项目!本专栏精选Web应用开发(Flask/Django)、数据分析可视化、自动化办公系统、简易爬虫框架、API接口开发等综合项目。通过需求分析、架构设计、编码实现、测试部署的全流程,深入掌握工程化开发、代码复用、调试排错与团队协作核心能力,积累高质量作品集,真正具备解决复杂问题的Python实战经验。


✨ 正文开始

为了让你能清晰掌握用Python实现飞机大战小游戏,我将教程分为环境准备、核心功能实现、游戏优化等模块,从基础的窗口创建到复杂的碰撞检测,逐步讲解并给出完整代码。

Python小游戏实战:打造一款视觉精美的飞机大战

一、前言

飞机大战作为经典的射击类小游戏,凭借简单的操作和紧张刺激的玩法,成为很多开发者入门游戏开发的首选案例。本次实战将使用Python的pygame库,从零开始打造一款画面精美、功能完整的飞机大战小游戏,涵盖窗口创建、角色绘制、碰撞检测、音效添加等核心知识点。即使是Python新手,也能通过本教程掌握2D小游戏开发的基本思路。

二、开发环境准备

2.1 核心库介绍

本次开发仅需依赖pygame库,它是Python中最常用的2D游戏开发库,提供了图形渲染、声音播放、事件处理等一系列游戏开发必需的功能,且语法简洁,易于上手。

2.2 环境搭建步骤

  • 安装Python:确保电脑已安装Python 3.6及以上版本(推荐3.8或3.9),可从Python官网下载安装。
  • 安装pygame库:打开命令提示符(Windows)或终端(Mac/Linux),输入以下命令安装:
  • pip install pygame

  • 验证安装:在Python交互环境中输入以下代码,若未报错则安装成功:
  • import pygame
    print(pygame.ver) # 输出pygame版本号即表示成功

    2.3 资源准备

    游戏需要用到图片和音效资源,可通过以下方式获取:

    • 图片资源:玩家飞机、敌机、子弹、背景图等,推荐从itch.io(免费游戏资源平台)或站酷下载,注意图片格式为png(支持透明背景,视觉效果更优)。
    • 音效资源:发射子弹、敌机爆炸、游戏结束等音效,推荐从FreeSound下载,格式为wav或mp3。

    将所有资源放在项目根目录下的images和sounds文件夹中,便于代码管理,目录结构如下:

    plane_war/
    ├─ images/
    │ ├─ player.png # 玩家飞机
    │ ├─ enemy.png # 敌机
    │ ├─ bullet.png # 子弹
    │ └─ background.png # 背景图
    ├─ sounds/
    │ ├─ shoot.wav # 发射子弹音效
    │ ├─ explode.wav # 敌机爆炸音效
    │ └─ game_over.wav # 游戏结束音效
    └─ main.py # 游戏主程序

    三、游戏核心功能实现(分模块讲解)

    3.1 游戏初始化与窗口创建

    首先初始化pygame,设置游戏窗口大小、标题,并加载背景图,实现背景的“滚动”效果(让画面更有动感)。

    import pygame
    import sys
    import random
    from pygame.locals import *

    # 初始化pygame
    pygame.init()

    # 游戏窗口设置
    SCREEN_WIDTH = 480 # 窗口宽度
    SCREEN_HEIGHT = 700 # 窗口高度
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    pygame.display.set_caption("Python飞机大战") # 窗口标题

    # 加载背景图并缩放(适配窗口大小)
    background = pygame.image.load("images/background.png").convert()
    background = pygame.transform.scale(background, (SCREEN_WIDTH, SCREEN_HEIGHT))

    # 背景滚动相关变量
    bg_y1 = 0 # 第一张背景图的y坐标
    bg_y2 = –SCREEN_HEIGHT # 第二张背景图的y坐标(初始在窗口上方)
    bg_speed = 2 # 背景滚动速度

    # 游戏主循环(暂时只实现背景滚动)
    clock = pygame.time.Clock() # 控制游戏帧率
    while True:
    # 1. 处理事件(如关闭窗口)
    for event in pygame.event.get():
    if event.type == QUIT:
    pygame.quit()
    sys.exit()

    # 2. 背景滚动逻辑
    bg_y1 += bg_speed
    bg_y2 += bg_speed
    # 当第一张背景图滚动到窗口外时,重置到第二张图上方
    if bg_y1 >= SCREEN_HEIGHT:
    bg_y1 = –SCREEN_HEIGHT
    # 同理重置第二张背景图
    if bg_y2 >= SCREEN_HEIGHT:
    bg_y2 = –SCREEN_HEIGHT

    # 3. 绘制背景
    screen.blit(background, (0, bg_y1))
    screen.blit(background, (0, bg_y2))

    # 4. 更新窗口显示
    pygame.display.update()
    clock.tick(60) # 固定游戏帧率为60FPS

    运行上述代码,会看到一个带有滚动背景的游戏窗口,这是游戏的基础框架。

    3.2 玩家飞机类(Player)实现

    玩家飞机需要支持鼠标或键盘控制移动、发射子弹等功能,我们用类来封装其属性和方法,使代码更模块化。

    class Player(pygame.sprite.Sprite):
    def __init__(self):
    super().__init__()
    # 加载玩家飞机图片并设置透明背景
    self.image = pygame.image.load("images/player.png").convert_alpha()
    # 缩放飞机图片(根据实际资源调整大小)
    self.image = pygame.transform.scale(self.image, (60, 48))
    # 获取飞机图片的矩形区域(用于定位和碰撞检测)
    self.rect = self.image.get_rect()
    # 初始位置:窗口底部中间
    self.rect.centerx = SCREEN_WIDTH // 2
    self.rect.bottom = SCREEN_HEIGHT – 10
    # 飞机移动速度
    self.speed = 5
    # 子弹冷却时间(避免连续发射时子弹过于密集)
    self.shoot_cooldown = 500 # 单位:毫秒
    self.last_shot = pygame.time.get_ticks() # 记录上次发射时间
    # 加载发射子弹音效
    self.shoot_sound = pygame.mixer.Sound("sounds/shoot.wav")
    self.shoot_sound.set_volume(0.3) # 降低音效音量(避免刺耳)

    def update(self):
    # 1. 鼠标控制飞机移动(更直观的操作方式)
    mouse_x, mouse_y = pygame.mouse.get_pos()
    # 限制飞机移动范围(不超出窗口)
    self.rect.centerx = max(30, min(mouse_x, SCREEN_WIDTH – 30))
    self.rect.centery = max(30, min(mouse_y, SCREEN_HEIGHT – 30))

    def shoot(self):
    # 检查是否超过冷却时间
    now = pygame.time.get_ticks()
    if now – self.last_shot > self.shoot_cooldown:
    self.last_shot = now
    # 创建子弹(位置在飞机头部)
    bullet = Bullet(self.rect.centerx, self.rect.top)
    all_sprites.add(bullet)
    player_bullets.add(bullet)
    # 播放发射音效
    self.shoot_sound.play()

    3.3 子弹类(Bullet)实现

    子弹分为玩家子弹和敌机子弹,这里先实现玩家子弹,后续再补充敌机子弹。

    class Bullet(pygame.sprite.Sprite):
    def __init__(self, x, y):
    super().__init__()
    # 加载子弹图片
    self.image = pygame.image.load("images/bullet.png").convert_alpha()
    self.image = pygame.transform.scale(self.image, (10, 20))
    self.rect = self.image.get_rect()
    # 子弹初始位置(飞机头部中央)
    self.rect.centerx = x
    self.rect.bottom = y
    # 子弹速度(向上飞行)
    self.speed = –10 # 负号表示y坐标减小(向上移动)

    def update(self):
    # 子弹移动
    self.rect.y += self.speed
    # 当子弹超出窗口顶部时,自动销毁(节省资源)
    if self.rect.bottom < 0:
    self.kill()

    3.4 敌机类(Enemy)实现

    敌机需要随机生成、向下移动,并且被玩家子弹击中后会爆炸并消失。

    class Enemy(pygame.sprite.Sprite):
    def __init__(self):
    super().__init__()
    # 加载敌机图片
    self.image = pygame.image.load("images/enemy.png").convert_alpha()
    self.image = pygame.transform.scale(self.image, (50, 40))
    self.rect = self.image.get_rect()
    # 随机生成敌机初始位置(窗口顶部,x坐标随机)
    self.rect.x = random.randint(0, SCREEN_WIDTH – self.rect.width)
    self.rect.y = random.randint(–100, –40) # 初始在窗口上方外
    # 敌机移动速度(随机,增加游戏难度变化)
    self.speed = random.randint(3, 5)
    # 加载爆炸音效
    self.explode_sound = pygame.mixer.Sound("sounds/explode.wav")
    self.explode_sound.set_volume(0.3)

    def update(self):
    # 敌机向下移动
    self.rect.y += self.speed
    # 当敌机超出窗口底部时,自动销毁
    if self.rect.top > SCREEN_HEIGHT:
    self.kill()

    def explode(self):
    # 播放爆炸音效
    self.explode_sound.play()
    # (可选)添加爆炸动画(后续优化部分讲解)
    pass

    3.5 碰撞检测与计分系统

    使用pygame的sprite模块提供的碰撞检测函数,实现“子弹击中敌机”和“敌机撞击玩家”的逻辑,并添加计分功能。

    在主程序中添加以下变量(放在游戏初始化部分):

    # 精灵组(用于统一管理角色和碰撞检测)
    all_sprites = pygame.sprite.Group() # 所有精灵(玩家、敌机、子弹)
    player_bullets = pygame.sprite.Group() # 玩家子弹(单独分组,便于碰撞检测)
    enemies = pygame.sprite.Group() # 敌机(单独分组)

    # 创建玩家
    player = Player()
    all_sprites.add(player)

    # 敌机生成定时器(每隔一定时间生成一架敌机)
    ENEMY_SPAWN_EVENT = pygame.USEREVENT + 1 # 自定义事件
    pygame.time.set_timer(ENEMY_SPAWN_EVENT, 800) # 800毫秒生成一架敌机

    # 计分系统
    score = 0
    font = pygame.font.Font(None, 36) # 字体(None表示使用系统默认字体,36为字号)
    text_color = (255, 255, 255) # 白色文字

    # 游戏结束标志
    game_over = False
    game_over_font = pygame.font.Font(None, 64)
    game_over_text = game_over_font.render("Game Over", True, (255, 0, 0)) # 红色“Game Over”
    restart_text = font.render("Press R to Restart", True, text_color)

    在主循环中添加碰撞检测、计分和游戏结束逻辑:

    while True:
    # 处理事件
    for event in pygame.event.get():
    if event.type == QUIT:
    pygame.quit()
    sys.exit()
    # 生成敌机(仅在游戏未结束时)
    if event.type == ENEMY_SPAWN_EVENT and not game_over:
    enemy = Enemy()
    all_sprites.add(enemy)
    enemies.add(enemy)
    # 鼠标点击发射子弹(左键)
    if event.type == MOUSEBUTTONDOWN and event.button == 1 and not game_over:
    player.shoot()
    # 按R键重新开始游戏(游戏结束后)
    if event.type == KEYDOWN and event.key == K_r and game_over:
    # 重置游戏状态
    game_over = False
    score = 0
    # 清空所有精灵
    all_sprites.empty()
    enemies.empty()
    player_bullets.empty()
    # 重新创建玩家
    player = Player()
    all_sprites.add(player)

    if not game_over:
    # 1. 更新所有精灵(移动、子弹销毁等)
    all_sprites.update()

    # 2. 子弹击中敌机的碰撞检测(精灵组与精灵组碰撞)
    # pygame.sprite.groupcollide(组1, 组2, 组1精灵碰撞后是否销毁, 组2精灵碰撞后是否销毁)
    hits = pygame.sprite.groupcollide(enemies, player_bullets, True, True)
    for hit in hits:
    # 每击中一架敌机,分数+10
    score += 10
    # (可选)击中后生成爆炸效果
    hit.explode()

    # 3. 敌机撞击玩家的碰撞检测(精灵与精灵组碰撞)
    if pygame.sprite.spritecollide(player, enemies, True):
    # 播放游戏结束音效
    game_over_sound = pygame.mixer.Sound("sounds/game_over.wav")
    game_over_sound.play()
    game_over = True

    # 4. 绘制背景
    bg_y1 += bg_speed
    bg_y2 += bg_speed
    if bg_y1 >= SCREEN_HEIGHT:
    bg_y1 = –SCREEN_HEIGHT
    if bg_y2 >= SCREEN_HEIGHT:
    bg_y2 = –SCREEN_HEIGHT
    screen.blit(background, (0, bg_y1))
    screen.blit(background, (0, bg_y2))

    # 5. 绘制所有精灵(仅在游戏未结束时)
    if not game_over:
    all_sprites.draw(screen)

    # 6. 绘制分数
    score_text = font.render(f"Score: {score}", True, text_color)
    screen.blit(score_text, (10, 10)) # 分数显示在窗口左上角

    # 7. 绘制游戏结束界面(游戏结束时)
    if game_over:
    # 居中显示“Game Over”和“重新开始”提示
    screen.blit(game_over_text, (SCREEN_WIDTH//2 – game_over_text.get_width()//2, SCREEN_HEIGHT//2 – 50))
    screen.blit(restart_text, (SCREEN_WIDTH//2 – restart_text.get_width()//2, SCREEN_HEIGHT//2 + 20))

    # 8. 更新窗口
    pygame.display.update()
    clock.tick(60)

    四、游戏优化(提升视觉和体验效果)

    4.1 添加爆炸动画

    敌机被击中后,仅播放音效不够直观,我们可以添加爆炸动画。首先准备一组爆炸序列帧图片(如explode_1.png、explode_2.png…),放在images文件夹中,然后创建爆炸类:

    class Explosion(pygame.sprite.Sprite):
    def __init__(self, x, y):
    super().__init__()
    # 加载爆炸序列帧
    self.explode_frames = []
    for i in range(1, 6): # 假设5张爆炸图片
    frame = pygame.image.load(f"images/explode_{i}.png").convert_alpha()
    frame = pygame.transform.scale(frame, (60, 60))
    self.explode_frames.append(frame)
    # 当前播放的帧索引
    self.frame_index = 0
    self.image = self.explode_frames[self.frame_index]
    self.rect = self.image.get_rect()
    self.rect.center = (x, y)
    # 帧切换时间(控制动画速度)
    self.last_update = pygame.time.get_ticks()
    self.frame_rate = 100 # 每100毫秒切换一帧

    def update(self):
    now = pygame.time.get_ticks()
    if now – self.last_update > self.frame_rate:
    self.last_update = now
    self.frame_index += 1
    # 当播放完所有帧后,销毁爆炸精灵
    if self.frame_index >= len(self.explode_frames):
    self.kill()
    else:
    self.image = self.explode_frames[self.frame_index]

    然后修改敌机被击中的逻辑(在主循环的hits处理中):

    for hit in hits:
    score += 10
    hit.explode()
    # 创建爆炸效果(在敌机位置)
    explosion = Explosion(hit.rect.centerx, hit.rect.centery)
    all_sprites.add(explosion)

    4.2 增加敌机种类和难度递增

    添加两种敌机:小型敌机(速度快、血量低)和大型敌机(速度慢、血量高、需要多颗子弹击中)。

    首先修改Enemy类,增加类型参数:

    class Enemy(pygame.sprite.Sprite):
    def __init__(self, enemy_type="small"):
    super().__init__()
    self.enemy_type = enemy_type
    # 根据类型加载不同图片和设置属性
    if self.enemy_type == "small":
    self.image = pygame.image.load("images/enemy_small.png").convert_alpha()
    self.image = pygame.transform.scale(self.image, (40, 30))
    self.speed = random.randint(3, 5)
    self.health = 1 # 生命值(1颗子弹即可击落)
    self.score = 10 # 击落得分
    elif self.enemy_type == "large":
    self.image = pygame.image.load("images/enemy_large.png").convert_alpha()
    self.image = pygame.transform.scale(self.image, (80, 60))
    self.speed = random.randint(1, 3)
    self.health = 3 # 需要3颗子弹才能击落
    self.score = 50 # 击落得分

    self.rect = self.image.get_rect()
    self.rect.x = random.randint(0, SCREEN_WIDTH – self.rect.width)
    self.rect.y = random.randint(–150, –50)
    self.explode_sound = pygame.mixer.Sound("sounds/explode.wav")
    self.explode_sound.set_volume(0.3)

    def hit(self):
    """处理被击中逻辑,返回是否被击落"""
    self.health -= 1
    if self.health <= 0:
    self.explode()
    return True, self.score
    return False, 0

    然后修改碰撞检测逻辑,支持多血量敌机:

    # 子弹击中敌机的碰撞检测
    hits = pygame.sprite.groupcollide(enemies, player_bullets, False, True)
    for enemy, bullets in hits.items():
    # 每颗子弹都造成伤害
    for bullet in bullets:
    destroyed, points = enemy.hit()
    if destroyed:
    score += points
    # 创建爆炸效果
    explosion = Explosion(enemy.rect.centerx, enemy.rect.centery)
    all_sprites.add(explosion)
    enemy.kill() # 从精灵组中移除
    break # 敌机已被击落,无需处理更多子弹

    为实现难度递增,可根据分数动态调整敌机生成频率和类型:

    # 在主程序初始化部分添加
    difficulty_timer = 0 # 难度计时器
    enemy_spawn_interval = 800 # 初始生成间隔(毫秒)

    # 在主循环中添加难度调整逻辑
    if not game_over:
    difficulty_timer += clock.get_time() # 累加时间(毫秒)

    # 每30秒增加一次难度
    if difficulty_timer >= 30000:
    difficulty_timer = 0
    # 减小生成间隔(最低300毫秒)
    enemy_spawn_interval = max(300, enemy_spawn_interval – 50)
    # 更新敌机生成定时器
    pygame.time.set_timer(ENEMY_SPAWN_EVENT, enemy_spawn_interval)

    # 修改敌机生成事件处理
    if event.type == ENEMY_SPAWN_EVENT and not game_over:
    # 随着分数提高,大型敌机出现概率增加
    if score < 500:
    enemy_type = "small" if random.random() < 0.9 else "large"
    else:
    enemy_type = "small" if random.random() < 0.7 else "large"
    enemy = Enemy(enemy_type)
    all_sprites.add(enemy)
    enemies.add(enemy)

    4.3 添加道具系统

    增加两种道具:

    • 子弹强化(临时提高射速)
    • 护盾(抵挡一次敌机撞击)

    首先创建道具类:

    class PowerUp(pygame.sprite.Sprite):
    def __init__(self, x, y, power_type):
    super().__init__()
    self.power_type = power_type
    # 根据类型加载不同图片
    if self.power_type == "bullet":
    self.image = pygame.image.load("images/powerup_bullet.png").convert_alpha()
    self.image = pygame.transform.scale(self.image, (30, 30))
    elif self.power_type == "shield":
    self.image = pygame.image.load("images/powerup_shield.png").convert_alpha()
    self.image = pygame.transform.scale(self.image, (30, 30))

    self.rect = self.image.get_rect()
    self.rect.center = (x, y)
    self.speed = 3 # 下落速度

    def update(self):
    self.rect.y += self.speed
    # 超出窗口底部则销毁
    if self.rect.top > SCREEN_HEIGHT:
    self.kill()

    在敌机被击落时,有概率生成道具:

    # 在敌机被击落的代码后添加
    # 10%概率生成道具
    if random.random() < 0.1:
    # 随机选择道具类型
    power_type = random.choice(["bullet", "shield"])
    powerup = PowerUp(enemy.rect.centerx, enemy.rect.centery, power_type)
    all_sprites.add(powerup)
    powerups.add(powerup) # 需要先定义powerups = pygame.sprite.Group()

    添加玩家与道具的碰撞检测:

    # 在主循环中添加
    powerup_hits = pygame.sprite.spritecollide(player, powerups, True)
    for powerup in powerup_hits:
    if powerup.power_type == "bullet":
    # 临时减少子弹冷却时间(持续5秒)
    player.shoot_cooldown = 200 # 从500ms减少到200ms
    pygame.time.set_timer(pygame.USEREVENT + 2, 5000, True) # 5秒后恢复
    elif powerup.power_type == "shield":
    player.shield = True # 需要在Player类中添加shield属性
    # 显示护盾效果(可在Player.update()中绘制护盾)

    五、完整代码整合

    将以上模块整合为完整代码,并添加必要的注释:

    import pygame
    import sys
    import random
    from pygame.locals import *

    # 飞机大战
    # 初始化pygame
    pygame.init()
    pygame.mixer.init() # 初始化音频系统

    # 游戏常量
    SCREEN_WIDTH = 480
    SCREEN_HEIGHT = 700
    FPS = 60

    # 颜色定义
    WHITE = (255, 255, 255)
    RED = (255, 0, 0)

    # 创建游戏窗口
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    pygame.display.set_caption("Python飞机大战")
    clock = pygame.time.Clock()

    # 加载资源
    def load_resource():
    resources = {}

    # 图片资源
    resources['background'] = pygame.image.load("images/background.png").convert()
    resources['background'] = pygame.transform.scale(resources['background'], (SCREEN_WIDTH, SCREEN_HEIGHT))

    resources['player'] = pygame.image.load("images/player.png").convert_alpha()
    resources['player'] = pygame.transform.scale(resources['player'], (60, 48))

    resources['bullet'] = pygame.image.load("images/bullet.png").convert_alpha()
    resources['bullet'] = pygame.transform.scale(resources['bullet'], (10, 20))

    resources['enemy_small'] = pygame.image.load("images/enemy_small.png").convert_alpha()
    resources['enemy_small'] = pygame.transform.scale(resources['enemy_small'], (40, 30))

    resources['enemy_large'] = pygame.image.load("images/enemy_large.png").convert_alpha()
    resources['enemy_large'] = pygame.transform.scale(resources['enemy_large'], (80, 60))

    # 爆炸帧动画
    resources['explosions'] = []
    for i in range(1, 6):
    img = pygame.image.load(f"images/explode_{i}.png").convert_alpha()
    img = pygame.transform.scale(img, (60, 60))
    resources['explosions'].append(img)

    # 道具图片
    resources['powerup_bullet'] = pygame.image.load("images/powerup_bullet.png").convert_alpha()
    resources['powerup_bullet'] = pygame.transform.scale(resources['powerup_bullet'], (30, 30))

    resources['powerup_shield'] = pygame.image.load("images/powerup_shield.png").convert_alpha()
    resources['powerup_shield'] = pygame.transform.scale(resources['powerup_shield'], (30, 30))

    # 音效资源
    resources['shoot_sound'] = pygame.mixer.Sound("sounds/shoot.mp3")
    resources['shoot_sound'].set_volume(0.3)

    resources['explode_sound'] = pygame.mixer.Sound("sounds/explode.mp3")
    resources['explode_sound'].set_volume(0.3)

    resources['powerup_sound'] = pygame.mixer.Sound("sounds/powerup.mp3")
    resources['powerup_sound'].set_volume(0.3)

    resources['game_over_sound'] = pygame.mixer.Sound("sounds/game_over.mp3")
    resources['game_over_sound'].set_volume(0.5)

    return resources

    # 加载所有资源
    resources = load_resource()

    # 玩家飞机类
    class Player(pygame.sprite.Sprite):
    def __init__(self):
    super().__init__()
    self.image = resources['player']
    self.rect = self.image.get_rect()
    self.rect.centerx = SCREEN_WIDTH // 2
    self.rect.bottom = SCREEN_HEIGHT – 10
    self.speed = 5
    self.shoot_cooldown = 500 # 子弹冷却时间(毫秒)
    self.last_shot = pygame.time.get_ticks()
    self.shoot_sound = resources['shoot_sound']
    self.shield = False # 是否有护盾
    self.shield_time = 0 # 护盾持续时间

    def update(self):
    # 鼠标控制移动
    mouse_x, mouse_y = pygame.mouse.get_pos()
    self.rect.centerx = max(30, min(mouse_x, SCREEN_WIDTH – 30))
    self.rect.centery = max(30, min(mouse_y, SCREEN_HEIGHT – 30))

    # 护盾效果处理
    if self.shield:
    self.shield_time += clock.get_time()
    if self.shield_time > 10000: # 护盾持续10秒
    self.shield = False
    self.shield_time = 0
    # 绘制护盾(半透明蓝色圆圈)
    pygame.draw.circle(screen, (0, 100, 255, 100),
    self.rect.center, self.rect.width // 2 + 5, 2)

    def shoot(self):
    now = pygame.time.get_ticks()
    if now – self.last_shot > self.shoot_cooldown:
    self.last_shot = now
    bullet = Bullet(self.rect.centerx, self.rect.top)
    all_sprites.add(bullet)
    player_bullets.add(bullet)
    self.shoot_sound.play()

    def reset(self):
    """重置玩家状态"""
    self.rect.centerx = SCREEN_WIDTH // 2
    self.rect.bottom = SCREEN_HEIGHT – 10
    self.shield = False
    self.shield_time = 0
    self.shoot_cooldown = 500

    # 子弹类
    class Bullet(pygame.sprite.Sprite):
    def __init__(self, x, y):
    super().__init__()
    self.image = resources['bullet']
    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()

    # 敌机类
    class Enemy(pygame.sprite.Sprite):
    def __init__(self, enemy_type="small"):
    super().__init__()
    self.enemy_type = enemy_type

    if self.enemy_type == "small":
    self.image = resources['enemy_small']
    self.speed = random.randint(3, 5)
    self.health = 1
    self.score = 10
    elif self.enemy_type == "large":
    self.image = resources['enemy_large']
    self.speed = random.randint(1, 3)
    self.health = 3
    self.score = 50

    self.rect = self.image.get_rect()
    self.rect.x = random.randint(0, SCREEN_WIDTH – self.rect.width)
    self.rect.y = random.randint(–150, –50)
    self.explode_sound = resources['explode_sound']

    def update(self):
    self.rect.y += self.speed
    if self.rect.top > SCREEN_HEIGHT:
    self.kill()

    def hit(self):
    self.health -= 1
    if self.health <= 0:
    self.explode()
    return True, self.score
    return False, 0

    def explode(self):
    self.explode_sound.play()

    # 爆炸效果类
    class Explosion(pygame.sprite.Sprite):
    def __init__(self, x, y):
    super().__init__()
    self.frames = resources['explosions']
    self.frame_index = 0
    self.image = self.frames[self.frame_index]
    self.rect = self.image.get_rect()
    self.rect.center = (x, y)
    self.last_update = pygame.time.get_ticks()
    self.frame_rate = 100 # 每100毫秒切换一帧

    def update(self):
    now = pygame.time.get_ticks()
    if now – self.last_update > self.frame_rate:
    self.last_update = now
    self.frame_index += 1
    if self.frame_index >= len(self.frames):
    self.kill()
    else:
    self.image = self.frames[self.frame_index]

    # 道具类
    class PowerUp(pygame.sprite.Sprite):
    def __init__(self, x, y, power_type):
    super().__init__()
    self.power_type = power_type
    if self.power_type == "bullet":
    self.image = resources['powerup_bullet']
    elif self.power_type == "shield":
    self.image = resources['powerup_shield']

    self.rect = self.image.get_rect()
    self.rect.center = (x, y)
    self.speed = 3
    self.sound = resources['powerup_sound']

    def update(self):
    self.rect.y += self.speed
    if self.rect.top > SCREEN_HEIGHT:
    self.kill()

    def apply(self, player):
    self.sound.play()
    if self.power_type == "bullet":
    player.shoot_cooldown = 200 # 临时提高射速
    pygame.time.set_timer(pygame.USEREVENT + 2, 5000, True) # 5秒后恢复
    elif self.power_type == "shield":
    player.shield = True
    player.shield_time = 0

    # 初始化精灵组
    all_sprites = pygame.sprite.Group()
    player_bullets = pygame.sprite.Group()
    enemies = pygame.sprite.Group()
    powerups = pygame.sprite.Group()

    # 创建玩家
    player = Player()
    all_sprites.add(player)

    # 游戏变量
    score = 0
    game_over = False
    enemy_spawn_interval = 800
    difficulty_timer = 0

    # 自定义事件
    ENEMY_SPAWN_EVENT = pygame.USEREVENT + 1
    pygame.time.set_timer(ENEMY_SPAWN_EVENT, enemy_spawn_interval)

    # 字体设置
    font = pygame.font.Font(None, 36)
    game_over_font = pygame.font.Font(None, 64)
    game_over_text = game_over_font.render("Game Over", True, RED)
    restart_text = font.render("Press R to Restart", True, WHITE)

    # 背景滚动变量
    bg_y1 = 0
    bg_y2 = –SCREEN_HEIGHT
    bg_speed = 2

    # 游戏主循环
    running = True
    while running:
    # 事件处理
    for event in pygame.event.get():
    if event.type == QUIT:
    running = False

    if event.type == ENEMY_SPAWN_EVENT and not game_over:
    # 根据分数调整敌机类型概率
    if score < 500:
    enemy_type = "small" if random.random() < 0.9 else "large"
    else:
    enemy_type = "small" if random.random() < 0.7 else "large"
    enemy = Enemy(enemy_type)
    all_sprites.add(enemy)
    enemies.add(enemy)

    if event.type == MOUSEBUTTONDOWN and event.button == 1 and not game_over:
    player.shoot()

    if event.type == KEYDOWN:
    if event.key == K_r and game_over:
    # 重置游戏
    game_over = False
    score = 0
    enemy_spawn_interval = 800
    pygame.time.set_timer(ENEMY_SPAWN_EVENT, enemy_spawn_interval)

    # 清空精灵组
    for sprite in all_sprites:
    if sprite != player:
    sprite.kill()
    enemies.empty()
    player_bullets.empty()
    powerups.empty()

    player.reset()

    # 子弹强化效果结束
    if event.type == pygame.USEREVENT + 2:
    player.shoot_cooldown = 500

    if not game_over:
    # 更新所有精灵
    all_sprites.update()

    # 背景滚动
    bg_y1 += bg_speed
    bg_y2 += bg_speed
    if bg_y1 >= SCREEN_HEIGHT:
    bg_y1 = –SCREEN_HEIGHT
    if bg_y2 >= SCREEN_HEIGHT:
    bg_y2 = –SCREEN_HEIGHT

    # 子弹击中敌机检测
    hits = pygame.sprite.groupcollide(enemies, player_bullets, False, True)
    for enemy, bullets in hits.items():
    for bullet in bullets:
    destroyed, points = enemy.hit()
    if destroyed:
    score += points
    explosion = Explosion(enemy.rect.centerx, enemy.rect.centery)
    all_sprites.add(explosion)
    enemy.kill()

    # 10%概率生成道具
    if random.random() < 0.1:
    power_type = random.choice(["bullet", "shield"])
    powerup = PowerUp(enemy.rect.centerx, enemy.rect.centery, power_type)
    all_sprites.add(powerup)
    powerups.add(powerup)
    break

    # 玩家拾取道具
    powerup_hits = pygame.sprite.spritecollide(player, powerups, True)
    for powerup in powerup_hits:
    powerup.apply(player)

    # 敌机撞击玩家检测
    enemy_hits = pygame.sprite.spritecollide(player, enemies, True)
    if enemy_hits:
    if not player.shield: # 没有护盾时才会游戏结束
    # 播放游戏结束音效
    resources['game_over_sound'].play()
    # 显示爆炸效果
    explosion = Explosion(player.rect.centerx, player.rect.centery)
    all_sprites.add(explosion)
    game_over = True
    else: # 有护盾时抵消一次伤害
    player.shield = False
    explosion = Explosion(enemy_hits[0].rect.centerx, enemy_hits[0].rect.centery)
    all_sprites.add(explosion)

    # 难度递增(每30秒)
    difficulty_timer += clock.get_time()
    if difficulty_timer >= 30000:
    difficulty_timer = 0
    enemy_spawn_interval = max(300, enemy_spawn_interval – 50)
    pygame.time.set_timer(ENEMY_SPAWN_EVENT, enemy_spawn_interval)

    # 绘制
    screen.blit(resources['background'], (0, bg_y1))
    screen.blit(resources['background'], (0, bg_y2))

    if not game_over:
    all_sprites.draw(screen)

    # 绘制分数
    score_text = font.render(f"Score: {score}", True, WHITE)
    screen.blit(score_text, (10, 10))

    # 绘制游戏结束界面
    if game_over:
    screen.blit(game_over_text, (SCREEN_WIDTH // 2 – game_over_text.get_width() // 2,
    SCREEN_HEIGHT // 2 – 50))
    screen.blit(restart_text, (SCREEN_WIDTH // 2 – restart_text.get_width() // 2,
    SCREEN_HEIGHT // 2 + 20))

    # 更新显示
    pygame.display.flip()
    clock.tick(FPS)

    # 退出游戏
    pygame.quit()
    sys.exit()

    运行效果:

    在这里插入图片描述

    游戏 结束效果图 :

    在这里插入图片描述

    六、游戏扩展与优化建议

  • 增加更多游戏元素:

    • Boss敌机(更大尺寸、更多血量、特殊攻击)
    • 多类型子弹(如散弹、激光等)
    • 关卡系统(不同关卡有不同的敌机组合)
  • 视觉效果优化:

    • 添加粒子效果(如子弹尾迹、爆炸碎片)
    • 实现飞机动画(如引擎喷射效果)
    • 添加背景分层滚动(增强立体感)
  • 游戏机制完善:

    • 增加生命值系统(初始3条命)
    • 实现排行榜(记录最高分)
    • 添加音效开关和音量调节
  • 代码结构优化:

    • 将不同角色类拆分到单独的模块文件
    • 添加资源加载失败的异常处理
    • 实现游戏设置界面(如难度选择)
  • 七、总结

    通过本教程,我们从零开始实现了一款功能完整、画面精美的飞机大战游戏,涵盖了游戏开发的核心知识点:

    • 游戏窗口创建与基本渲染
    • 角色类设计与精灵系统使用
    • 碰撞检测与游戏逻辑实现
    • 动画效果与音效处理
    • 难度递增与道具系统设计

    pygame库为2D游戏开发提供了便捷的接口,掌握这些基础知识后,你可以尝试扩展更多功能,或者开发其他类型的小游戏(如贪吃蛇、俄罗斯方块等)。游戏开发的乐趣在于不断创新和优化,希望本教程能为你的Python游戏开发之路提供帮助!

    🔥🔥🔥 相关热门书籍推荐:

    书名说明
    在这里插入图片描述 讲解 Python 中贝叶斯建模计算,理论与实践结合,适合数据科学领域学习贝叶斯方法的读者。 🥇 点击购买
    在这里插入图片描述 专注 Python 高性能技术,助力高效处理大数据集,提升编码与数据分析效率。 🥇 点击购买
    在这里插入图片描述 依托 PyTorch 和 Google Colab,深入深度学习核心,兼具理论与实践,适合学习者进阶。 🥇 点击购买

    附录:扩展学习资源

  • 官方资源:
    • Python官网:https://www.python.org
    • PyPI:https://pypi.org(查找第三方库)
    • 安装包等相关文件(另附带pycharm工具),网盘下载地址:https://pan.quark.cn/s/649af731037c
    • 学习资料视频和文档资源,网盘下载地址: https://pan.quark.cn/s/ee16901a8954
  • 本专栏特色资源:
    • 代码资源仓库:CSDN专属资源在线获取
    • 海量Python教程:关注公众号:xcLeigh,获取网盘地址
    • 一对一答疑:添加微信与博主在线沟通(备注“Python专栏”)
  • 联系博主

        xcLeigh 博主,全栈领域优质创作者,博客专家,目前,活跃在CSDN、微信公众号、小红书、知乎、掘金、快手、思否、微博、51CTO、B站、腾讯云开发者社区、阿里云开发者社区等平台,全网拥有几十万的粉丝,全网统一IP为 xcLeigh。希望通过我的分享,让大家能在喜悦的情况下收获到有用的知识。主要分享编程、开发工具、算法、技术学习心得等内容。很多读者评价他的文章简洁易懂,尤其对于一些复杂的技术话题,他能通过通俗的语言来解释,帮助初学者更好地理解。博客通常也会涉及一些实践经验,项目分享以及解决实际开发中遇到的问题。如果你是开发领域的初学者,或者在学习一些新的编程语言或框架,关注他的文章对你有很大帮助。

        亲爱的朋友,无论前路如何漫长与崎岖,都请怀揣梦想的火种,因为在生活的广袤星空中,总有一颗属于你的璀璨星辰在熠熠生辉,静候你抵达。

         愿你在这纷繁世间,能时常收获微小而确定的幸福,如春日微风轻拂面庞,所有的疲惫与烦恼都能被温柔以待,内心永远充盈着安宁与慰藉。

        至此,文章已至尾声,而您的故事仍在续写,不知您对文中所叙有何独特见解?期待您在心中与我对话,开启思想的新交流。


         💞 关注博主 🌀 带你实现畅游前后端!

         🏰 大屏可视化 🌀 带你体验酷炫大屏!

         💯 神秘个人简介 🌀 带你体验不一样得介绍!

         🥇 从零到一学习Python 🌀 带你玩转Python技术流!

         🏆 前沿应用深度测评 🌀 前沿AI产品热门应用在线等你来发掘!

         💦 注:本文撰写于CSDN平台,作者:xcLeigh(所有权归作者所有) ,https://xcleigh.blog.csdn.net/,如果相关下载没有跳转,请查看这个地址,相关链接没有跳转,皆是抄袭本文,转载请备注本文原地址。


    在这里插入图片描述

         📣 亲,码字不易,动动小手,欢迎 点赞 ➕ 收藏,如 🈶 问题请留言(或者关注下方公众号,看见后第一时间回复,还有海量编程资料等你来领!),博主看见后一定及时给您答复 💌💌💌

    赞(0)
    未经允许不得转载:171主机测评 » python小游戏实战:打造一款视觉精美的飞机大战
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址