基于Python与Pygame制作Flappy Bird小游戏的完整步骤

白榆
白榆
发布时间:2026-10-12| 2人浏览过
原创

本文详解使用Python与Pygame库搭建Flappy Bird小游戏的核心流程,涵盖环境配置、开始界面帧动画、主循环物理交互、像素级碰撞检测及计分系统实现,并提供完整的代码结构与命令行运行指南,帮助开发者快速掌握2D休闲游戏的开发逻辑。

开发环境准备

完成本项目的开发需满足以下基础条件:

  • 编程语言:Python(原文基于3.6.4版本,建议实际环境升级至3.8以上以获得更好的性能与包管理支持)
  • 核心依赖:pygame 图形音频库,以及Python标准库(如itertools)
  • 环境配置:安装Python后将解释器加入系统环境变量,确保在终端可直接调用python命令。

使用pip安装依赖模块即可开始编码:

pip install pygame

核心逻辑设计与代码实现

游戏采用状态机模式划分,主要分为“开始界面”、“主游戏循环”与“结算界面”三个阶段。以下为各阶段的核心实现步骤与关键代码。

第1步:初始化游戏常量与资源参数

所有外部配置(如屏幕宽高、刷新率FPS、角色初始位置等)应统一封装在配置文件(通常为cfg.py)中。主程序启动时需读取这些参数,并负责加载背景图、角色贴图、音效等资源字典。这一步是后续所有坐标计算与渲染的基准。

第2步:编写开始界面与动态背景逻辑

开始界面的视觉重点在于营造飞行假象。主要依赖三个循环机制:

  1. 地板滚动:将背景与地板的宽度差作为偏移量基准,通过取模运算实现无缝向左平移。
  2. 小鸟扇翅:利用itertools.cycle生成[0, 1, 2, 1]的帧索引序列,每5帧切换一次贴图,形成连续拍打动画。
  3. 悬停上下起伏:通过累加计数器控制位移方向变量shift的正负反转,使小鸟在垂直方向做规律波动。
开始界面视觉效果示意图
开始界面需呈现地板滚动与小鸟悬停的连续动态效果

具体渲染与事件监听代码如下:

'''显示开始界面'''
def startGame(screen, sounds, bird_images, other_images, backgroud_image, cfg):
    base_pos = [0, cfg.SCREENHEIGHT * 0.79]
    base_diff_bg = other_images['base'].get_width() - backgroud_image.get_width()
    msg_pos = [(cfg.SCREENWIDTH - other_images['message'].get_width()) / 2, cfg.SCREENHEIGHT * 0.12]
    
    bird_idx = 0
    bird_idx_change_count = 0
    bird_idx_cycle = itertools.cycle([0, 1, 2, 1])
    bird_pos = [cfg.SCREENWIDTH * 0.2, (cfg.SCREENHEIGHT - list(bird_images.values())[0].get_height()) / 2]
    bird_y_shift_count = 0
    bird_y_shift_max = 9
    shift = 1
    
    clock = pygame.time.Clock()
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE or event.key == pygame.K_UP:
                    return {'bird_pos': bird_pos, 'base_pos': base_pos, 'bird_idx': bird_idx}
                    
        sounds['wing'].play()
        bird_idx_change_count += 1
        if bird_idx_change_count % 5 == 0:
            bird_idx = next(bird_idx_cycle)
            bird_idx_change_count = 0
            
        base_pos[0] = -((-base_pos[0] + 4) % base_diff_bg)
        bird_y_shift_count += 1
        if bird_y_shift_count == bird_y_shift_max:
            bird_y_shift_max = 16
            shift = -1 * shift
            bird_y_shift_count = 0
        bird_pos[-1] = bird_pos[-1] + shift
        
        screen.blit(backgroud_image, (0, 0))
        screen.blit(list(bird_images.values())[bird_idx], bird_pos)
        screen.blit(other_images['message'], msg_pos)
        screen.blit(other_images['base'], base_pos)
        pygame.display.update()
        clock.tick(cfg.FPS)

第3步:实现主游戏循环与管道生成机制

进入主循环后,除延续背景移动外,需新增管道实体组、处理玩家输入的物理反馈,并管理道具生命周期。

小鸟翅膀扇动多帧素材示意
主循环中需实时渲染管道组、动态背景与角色状态

按键响应部分,按下空格或上箭头时触发上升速度叠加,配合每帧衰减的重力参数,模拟真实的加速度运动。管道生成采用预分配策略,初始随机创建两对,随后在首个管道触及特定横坐标时补充新管道,并在完全移出左边界后安全销毁以避免内存泄漏。

主循环核心控制流如下:

# 进入主游戏
score = 0
bird_pos, base_pos, bird_idx = list(game_start_info.values())
base_diff_bg = other_images['base'].get_width() - backgroud_image.get_width()
clock = pygame.time.Clock()

# 初始化管道精灵组
pipe_sprites = pygame.sprite.Group()
for i in range(2):
    pipe_pos = Pipe.randomPipe(cfg, pipe_images.get('top'))
    pipe_sprites.add(Pipe(image=pipe_images.get('top'), position=(cfg.SCREENWIDTH + 200 + i * cfg.SCREENWIDTH / 2, pipe_pos.get('top')[-1])))
    pipe_sprites.add(Pipe(image=pipe_images.get('bottom'), position=(cfg.SCREENWIDTH + 200 + i * cfg.SCREENWIDTH / 2, pipe_pos.get('bottom')[-1])))

bird = Bird(images=bird_images, idx=bird_idx, position=bird_pos)
is_add_pipe = True
is_game_running = True

while is_game_running:
    # 事件监听与跳跃反馈
    for event in pygame.event.get():
        if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
            pygame.quit()
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE or event.key == pygame.K_UP:
                bird.setFlapped()
                sounds['wing'].play()

    # 移动地板与管道组
    base_pos[0] = -((-base_pos[0] + 4) % base_diff_bg)
    flag = False
    for pipe in pipe_sprites:
        pipe.rect.left -= 4
        
        # 计分逻辑:穿越缺口时标记并加分
        if pipe.rect.centerx < bird.rect.centerx and not pipe.used_for_score:
            pipe.used_for_score = True
            score += 0.5
            if '.5' in str(score):
                sounds['point'].play()
                
        # 补充与清理管道
        if pipe.rect.left < 5 and pipe.rect.left > 0 and is_add_pipe:
            pipe_pos = Pipe.randomPipe(cfg, pipe_images.get('top'))
            pipe_sprites.add(Pipe(image=pipe_images.get('top'), position=pipe_pos.get('top')))
            pipe_sprites.add(Pipe(image=pipe_images.get('bottom'), position=pipe_pos.get('bottom')))
            is_add_pipe = False
        elif pipe.rect.right < 0:
            pipe_sprites.remove(pipe)
            flag = True
            
    if flag: is_add_pipe = True
    
    # 物理更新与边界检测
    boundary_values = [0, base_pos[-1]]
    is_dead = bird.update(boundary_values, float(clock.tick(cfg.FPS)) / 1000.)
    if is_dead:
        sounds['hit'].play()
        is_game_running = False
        
    # 绘制当前帧
    screen.blit(backgroud_image, (0, 0))
    pipe_sprites.draw(screen)
    screen.blit(other_images['base'], base_pos)
    showScore(screen, score, number_images)
    bird.draw(screen)
    pygame.display.update()
    clock.tick(cfg.FPS)

第4步:处理碰撞检测与结算界面

为保证打击感与判定准确度,弃用传统的矩形相交测试,改用像素级掩码检测:pygame.sprite.collide_mask。当小鸟主体或管道边缘重叠超过透明像素阈值时,判定为撞击并触发失败音效。

程序运行结果截图
成功穿越管道区域可触发得分提示,撞击则进入结算态

游戏结束后进入静态等待界面,小鸟受重力影响持续下落直至触碰底线。此时监听键盘信号,再次按下空格或上键即可重置状态返回主循环。

'''游戏结束界面'''
def endGame(screen, sounds, showScore, score, number_images, bird, pipe_sprites, backgroud_image, other_images, base_pos, cfg):
    sounds['die'].play()
    clock = pygame.time.Clock()
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE or event.key == pygame.K_UP:
                    return
                    
        boundary_values = [0, base_pos[-1]]
        bird.update(boundary_values, float(clock.tick(cfg.FPS)) / 1000.)
        
        screen.blit(backgroud_image, (0, 0))
        pipe_sprites.draw(screen)
        screen.blit(other_images['base'], base_pos)
        showScore(screen, score, number_images)
        bird.draw(screen)
        pygame.display.update()
        clock.tick(cfg.FPS)

运行验证与排错指引

完成代码整理后,打开终端进入工程根目录,执行以下命令启动游戏:

python Game6.py

若遇到报错,请按以下顺序排查:

  • ModuleNotFoundError: 确认未激活虚拟环境或未正确安装pygame。尝试运行pip install pygame --upgrade重新获取最新版。
  • AttributeError/KeyError: 检查配置文件cfg中的路径映射是否与实际资源文件夹名称一致。原代码高度依赖全局字典键名(如'base', 'top'),修改贴图路径时需同步更新字典。
  • 窗口黑屏/无响应: 检查是否遗漏了pygame.init()初始化调用,或分辨率参数SCREENWIDTH/HEIGHT超出当前显示器适配范围。

总结

通过以上四个阶段的拆解,可以清晰看到一款2D跑酷游戏从画面铺陈到物理演算的完整链路。掌握精灵帧控制、掩码碰撞与事件分发机制后,即可在此基础上替换美术资源或增加道具系统。以上就是基于Python制作Flappy Bird小游戏的详细步骤,更多关于Python游戏开发与Pygame实战的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。