Python开发飞机大战全教程(四)

简介: 教程来源 https://bncne.cn 本教程基于Pygame实现经典“飞机大战”游戏,含玩家控制、子弹射击、敌机生成与碰撞检测等核心功能。代码结构清晰,支持键盘操作(方向键移动、空格射击、R键重开),并提供图像替换、爆炸动画、滚动星空背景及动态难度提升等扩展方案,助你从零掌握游戏开发全流程。

第七部分:完整代码整合

现在把所有部分整合成完整的游戏代码,文件命名为plane_game.py:

import pygame
import sys
import random

# ========== 初始化 ==========
pygame.init()
pygame.font.init()

# ========== 常量定义 ==========
SCREEN_WIDTH = 480
SCREEN_HEIGHT = 700
FPS = 60

# 颜色常量(RGB)
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)

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

# ========== 字体 ==========
font = pygame.font.Font(None, 36)


# ========== 玩家类 ==========
class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.Surface((50, 50))
        self.image.fill(BLUE)
        self.rect = self.image.get_rect()
        self.rect.centerx = SCREEN_WIDTH // 2
        self.rect.bottom = SCREEN_HEIGHT - 10

        # 移动速度
        self.speed = 5
        # 移动方向标记
        self.moving_left = False
        self.moving_right = False
        self.moving_up = False
        self.moving_down = False

        # 射击冷却
        self.shoot_delay = 10
        self.shoot_timer = 0

    def update(self):
        # 更新射击冷却
        if self.shoot_timer > 0:
            self.shoot_timer -= 1

        # 移动
        if self.moving_left:
            self.rect.x -= self.speed
        if self.moving_right:
            self.rect.x += self.speed
        if self.moving_up:
            self.rect.y -= self.speed
        if self.moving_down:
            self.rect.y += self.speed

        # 边界限制
        if self.rect.left < 0:
            self.rect.left = 0
        if self.rect.right > SCREEN_WIDTH:
            self.rect.right = SCREEN_WIDTH
        if self.rect.top < 0:
            self.rect.top = 0
        if self.rect.bottom > SCREEN_HEIGHT:
            self.rect.bottom = SCREEN_HEIGHT

    def can_shoot(self):
        return self.shoot_timer <= 0

    def shoot(self):
        if self.can_shoot():
            self.shoot_timer = self.shoot_delay
            return Bullet(self.rect.centerx, self.rect.top)
        return None


# ========== 子弹类 ==========
class Bullet(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface((5, 10))
        self.image.fill(YELLOW)
        self.rect = self.image.get_rect()
        self.rect.centerx = x
        self.rect.bottom = y
        self.speed_y = -8

    def update(self):
        self.rect.y += self.speed_y
        if self.rect.bottom < 0:
            self.kill()


# ========== 敌机类 ==========
class Enemy(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.Surface((40, 40))
        self.image.fill(RED)
        self.rect = self.image.get_rect()
        self.rect.x = random.randint(0, SCREEN_WIDTH - self.rect.width)
        self.rect.y = random.randint(-100, -40)
        self.speed_y = random.randint(3, 8)

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


# ========== 游戏初始状态 ==========
def init_game():
    """初始化游戏状态"""
    global all_sprites, bullets, enemies, player, score, game_over, enemy_spawn_timer

    # 精灵组
    all_sprites = pygame.sprite.Group()
    bullets = pygame.sprite.Group()
    enemies = pygame.sprite.Group()

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

    # 游戏变量
    score = 0
    game_over = False
    enemy_spawn_timer = 0


# ========== 主函数 ==========
def main():
    global all_sprites, bullets, enemies, player, score, game_over, enemy_spawn_timer

    init_game()
    running = True

    while running:
        # ---------- 1. 事件处理 ----------
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

            # 键盘按下
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    player.moving_left = True
                if event.key == pygame.K_RIGHT:
                    player.moving_right = True
                if event.key == pygame.K_UP:
                    player.moving_up = True
                if event.key == pygame.K_DOWN:
                    player.moving_down = True

                # 发射子弹
                if event.key == pygame.K_SPACE and not game_over:
                    bullet = player.shoot()
                    if bullet:
                        all_sprites.add(bullet)
                        bullets.add(bullet)

                # 重新开始
                if event.key == pygame.K_r and game_over:
                    init_game()

            # 键盘释放
            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT:
                    player.moving_left = False
                if event.key == pygame.K_RIGHT:
                    player.moving_right = False
                if event.key == pygame.K_UP:
                    player.moving_up = False
                if event.key == pygame.K_DOWN:
                    player.moving_down = False

        # ---------- 2. 游戏逻辑更新(仅在未结束时) ----------
        if not game_over:
            # 生成敌机
            enemy_spawn_timer += 1
            if enemy_spawn_timer >= 40:
                enemy_spawn_timer = 0
                enemy = Enemy()
                all_sprites.add(enemy)
                enemies.add(enemy)

            # 更新所有精灵
            all_sprites.update()

            # 子弹击中敌机
            hits = pygame.sprite.groupcollide(bullets, enemies, True, True)
            score += len(hits) * 10

            # 玩家与敌机碰撞
            if pygame.sprite.spritecollide(player, enemies, False):
                game_over = True

        # ---------- 3. 绘制 ----------
        # 清屏
        screen.fill(BLACK)

        # 绘制所有精灵
        all_sprites.draw(screen)

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

        # 游戏结束显示
        if game_over:
            text = font.render("GAME OVER - Press R to restart", True, RED)
            text_rect = text.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2))
            screen.blit(text, text_rect)

        # 刷新屏幕
        pygame.display.flip()

        # 控制帧率
        clock.tick(FPS)

    pygame.quit()
    sys.exit()


if __name__ == "__main__":
    main()

第八部分:游戏测试与调试

8.1 运行游戏
在终端中执行:

python plane_game.py

控制方式:

方向键:移动飞机
http://yvyus.cn
空格键:发射子弹

R键:游戏结束后重新开始

8.2 常见问题与解决方法
image.png

第九部分:扩展功能

9.1 添加图像(替换矩形)
准备三张图片:player.png(玩家飞机)、enemy.png(敌机)、bullet.png(子弹),放到项目同目录下。

修改精灵类的init方法:

class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        # 加载图片,convert_alpha()可提高绘制速度并保留透明背景
        self.image = pygame.image.load("player.png").convert_alpha()
        self.rect = self.image.get_rect()
        # ...其他代码

9.2 添加爆炸效果

class Explosion(pygame.sprite.Sprite):
    def __init__(self, center):
        super().__init__()
        self.images = []  # 动画帧列表
        # 创建多个爆炸图形模拟动画
        for size in range(1, 6):
            surf = pygame.Surface((size * 8, size * 8))
            surf.fill((255, 100, 0))
            self.images.append(surf)
        self.index = 0
        self.image = self.images[self.index]
        self.rect = self.image.get_rect(center=center)

    def update(self):
        self.index += 1
        if self.index >= len(self.images):
            self.kill()
        else:
            self.image = self.images[self.index]

9.3 添加背景滚动效果

class Background:
    def __init__(self):
        self.bg_image = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
        # 在背景上画星星
        for _ in range(100):
            x = random.randint(0, SCREEN_WIDTH)
            y = random.randint(0, SCREEN_HEIGHT)
            pygame.draw.circle(self.bg_image, WHITE, (x, y), 1)
        self.bg_y1 = 0
        self.bg_y2 = -SCREEN_HEIGHT

    def update(self):
        self.bg_y1 += 2
        self.bg_y2 += 2
        if self.bg_y1 >= SCREEN_HEIGHT:
            self.bg_y1 = -SCREEN_HEIGHT
        if self.bg_y2 >= SCREEN_HEIGHT:
            self.bg_y2 = -SCREEN_HEIGHT

    def draw(self, screen):
        screen.blit(self.bg_image, (0, self.bg_y1))
        screen.blit(self.bg_image, (0, self.bg_y2))

9.4 添加难度梯度
随着分数增加,敌人生成速度加快、敌机速度增加:

# 计算当前难度系数
difficulty = min(score // 500, 3)  # 最大难度系数3
enemy_spawn_delay = max(20, 40 - difficulty * 5)  # 40 → 35 → 30 → 25
enemy_speed = random.randint(3, 8 + difficulty)    # 敌机更快

游戏开发是一个迭代的过程,可以先实现基础功能,再逐步添加特效。希望你能通过这个项目掌握Pygame开发的核心技能,并创造出属于自己的游戏作品!

相关文章
|
7天前
|
缓存 人工智能 自然语言处理
我对比了8个Claude API中转站,踩了不少坑,总结给你
本文是个人开发者耗时1周实测的8大Claude中转平台横向评测,聚焦Claude Code真实体验:以加权均价(¥/M token)、内部汇率、缓存支持、模型真实性及稳定性为核心指标。
2988 20
|
19天前
|
人工智能 自然语言处理 安全
Claude Code 全攻略:命令大全 + 实战工作流(建议收藏)
本文介绍了Claude Code终端AI助手的使用指南,主要内容包括:1)常用命令如版本查看、项目启动和更新;2)三种工作模式切换及界面说明;3)核心功能指令速查表,包含初始化、压缩对话、清除历史等操作;4)详细解析了/init、/help、/clear、/compact、/memory等关键命令的使用场景和语法。文章通过丰富的界面截图和场景示例,帮助开发者快速掌握如何通过命令行和交互界面高效使用Claude Code进行项目开发,特别强调了CLAUDE.md文件作为项目知识库的核心作用。
16980 53
Claude Code 全攻略:命令大全 + 实战工作流(建议收藏)
|
14天前
|
人工智能 JavaScript Ubuntu
低成本搭建AIP自动化写作系统:Hermes保姆级使用教程,长文和逐步实操贴图
我带着怀疑的态度,深度使用了几天,聚焦微信公众号AIP自动化写作场景,写出来的几篇文章,几乎没有什么修改,至少合乎我本人的意愿,而且排版风格,也越来越完善,同样是起码过得了我自己这一关。 这个其实OpenClaw早可以实现了,但是目前我觉得最大的区别是,Hermes会自主总结提炼,并更新你的写作技能。 相信就冲这一点,就值得一试。 这篇帖子主要就Hermes部署使用,作一个非常详细的介绍,几乎一步一贴图。 关于Hermes,无论你赞成哪种声音,我希望都是你自己动手行动过,发自内心的选择!
3117 29
|
4天前
|
人工智能 测试技术 API
阿里Qwen3.6-27B正式开源:网友直呼“太牛了”!
阿里云千问3.6系列重磅开源Qwen3.6-27B稠密大模型!官网:https://t.aliyun.com/U/JbblVp 仅270亿参数,编程能力媲美千亿模型,在SWE-bench等权威基准中表现卓越。支持多模态理解、本地部署及OpenClaw等智能体集成,已开放Hugging Face与ModelScope下载。
|
3天前
|
机器学习/深度学习 缓存 测试技术
DeepSeek-V4开源:百万上下文,Agent能力比肩顶级闭源模型
DeepSeek-V4正式开源!含V4-Pro(1.6T参数)与V4-Flash(284B参数)双版本,均支持百万token上下文。首创混合注意力架构,Agent能力、世界知识与推理性能全面领先开源模型,数学/代码评测比肩顶级闭源模型。
1597 6
|
3天前
|
人工智能 JSON BI
DeepSeek V4 来了!超越 Claude Sonnet 4.5,赶紧对接 Claude Code 体验一把
JeecgBoot AI专题研究 把 Claude Code 接入 DeepSeek V4Pro 的真实体验与避坑记录 本文记录我将 Claude Code 对接 DeepSeek 最新模型(V4Pro)后的真实体验,测试了 Skills 自动化查询和积木报表 AI 建表两个场景——有惊喜,也踩
1272 6