
1. 引言
Flappy Bird 是一款曾经火爆全网的小游戏,玩家通过点按屏幕控制小鸟飞行,躲避上下移动的管道障碍,同时累积得分。
今天我们就来尝试用 Python 的 Pygame 库,从零开始开发一个 Flappy Bird 游戏。通过本篇教程,你可以:
2. 环境搭建
2.1 安装 Python 和 Pygame
确保你的电脑已安装 Python 3.x(推荐 3.8 或以上)。通过 pip 命令安装 Pygame:
pip install pygame2.2 创建项目目录
创建一个项目文件夹(如 flappy_bird),并在其中新建一个 Python 文件(如 flappy_bird.py)。为了美观游戏界面,准备以下资源(可从网络下载免费像素风格素材,或用简单颜色替代):
将这些资源放在项目文件夹的 assets 子目录中。
2.3 测试 Pygame 窗口
让我们先创建一个简单的 Pygame 窗口,确认环境正常:
import pygame
pygame.init()
screen = pygame.display.set_mode((400, 600))
pygame.display.set_caption("Flappy Bird")
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
screen.fill((0, 0, 0))
pygame.display.flip()
pygame.quit()运行这段代码,你会看到一个 400x600 像素的黑色窗口。按关闭按钮退出。

3. 游戏设计
3.1 核心元素
Flappy Bird 包含以下主要元素:
3.2 游戏规则
3.3 技术要点
4. 代码实现
以下是逐步实现 Flappy Bird 的代码和讲解。我们将代码分为模块化部分,确保清晰且易于扩展。
4.1 初始化游戏
首先,设置游戏窗口、加载资源并初始化基本参数:
import pygame
import random
# 初始化 Pygame
pygame.init()
# 游戏窗口设置
SCREEN_WIDTH = 400
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Flappy Bird")
clock = pygame.time.Clock()
FPS = 60
# 颜色
WHITE = (255, 255, 255)
# 加载资源(替换为你的图片路径)
try:
BIRD_IMG = pygame.image.load("assets/bird.png").convert_alpha()
PIPE_IMG = pygame.image.load("assets/pipe.png").convert_alpha()
BG_IMG = pygame.image.load("assets/background.png").convert()
BASE_IMG = pygame.image.load("assets/base.png").convert_alpha()
except FileNotFoundError:
print("资源文件未找到,请确保 assets 文件夹中有 bird.png, pipe.png, background.png, base.png")
pygame.quit()
exit()
# 游戏变量
GRAVITY = 0.5
JUMP_HEIGHT = -10
PIPE_GAP = 150
PIPE_SPEED = 3这里我们定义了窗口大小(400x600)、帧率(60 FPS)、重力加速度、跳跃高度、管道间距和移动速度。如果没有图片资源,可以用简单的矩形代替(后续会说明)。

4.2 小鸟逻辑
创建一个 Bird 类,管理小鸟的位置、速度和绘制:
class Bird:
def __init__(self):
self.x = 100
self.y = SCREEN_HEIGHT // 2
self.velocity = 0
self.image = BIRD_IMG
self.rect = self.image.get_rect(topleft=(self.x, self.y))
def jump(self):
self.velocity = JUMP_HEIGHT
def update(self):
self.velocity += GRAVITY
self.y += self.velocity
self.rect.y = self.y
def draw(self, screen):
screen.blit(self.image, self.rect)jump:按空格键或点击时,设置向上的速度。
update:每帧更新小鸟位置,模拟重力。
draw:绘制小鸟到屏幕。
如果没有图片,可以用矩形代替:
# 替代图片
pygame.draw.rect(screen, (255, 255, 0), (self.x, self.y, 30, 30))4.3 管道逻辑
创建一个 Pipe 类,管理管道的生成和移动:
class Pipe:
def __init__(self):
self.x = SCREEN_WIDTH
self.height = random.randint(150, 400)
self.passed = False
self.top_rect = PIPE_IMG.get_rect(bottomleft=(self.x, self.height - PIPE_GAP))
self.bottom_rect = PIPE_IMG.get_rect(topleft=(self.x, self.height))
def update(self):
self.x -= PIPE_SPEED
self.top_rect.x = self.bottom_rect.x = self.x
def draw(self, screen):
screen.blit(PIPE_IMG, self.top_rect)
flipped_pipe = pygame.transform.flip(PIPE_IMG, False, True)
screen.blit(flipped_pipe, self.bottom_rect)管道随机生成高度(150-400 像素),上下管道间距为 PIPE_GAP。
update 使管道向左移动。
draw 绘制上下管道(上管道翻转图片)。
如果没有管道图片,可用绿色矩形:
pygame.draw.rect(screen, (0, 255, 0), (self.x, 0, 50, self.height - PIPE_GAP))
pygame.draw.rect(screen, (0, 255, 0), (self.x, self.height, 50, SCREEN_HEIGHT - self.height))4.4 游戏循环
整合小鸟、管道、背景和地面,添加游戏循环:
# 地面类
class Base:
def __init__(self):
self.x = 0
self.y = SCREEN_HEIGHT - 100
self.image = BASE_IMG
self.width = self.image.get_width()
def update(self):
self.x -= PIPE_SPEED
if self.x <= -self.width:
self.x += self.width
def draw(self, screen):
screen.blit(self.image, (self.x, self.y))
screen.blit(self.image, (self.x + self.width, self.y))
# 主游戏循环
bird = Bird()
pipes = []
base = Base()
score = 0
font = pygame.font.SysFont("arial", 30)
pipe_timer = 0
running = True
while running:
# 事件处理
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
bird.jump()
if event.type == pygame.MOUSEBUTTONDOWN:
bird.jump()
# 更新
bird.update()
base.update()
# 生成管道
pipe_timer += 1
if pipe_timer > 90: # 每 1.5 秒生成一对管道
pipes.append(Pipe())
pipe_timer = 0
# 更新管道
for pipe in pipes[:]:
pipe.update()
if pipe.x < -pipe.top_rect.width:
pipes.remove(pipe)
if not pipe.passed and pipe.x < bird.x:
pipe.passed = True
score += 1
# 碰撞检测
for pipe in pipes:
if bird.rect.colliderect(pipe.top_rect) or bird.rect.colliderect(pipe.bottom_rect):
running = False
if bird.y <= 0 or bird.y >= SCREEN_HEIGHT - 100:
running = False
# 绘制
screen.blit(BG_IMG, (0, 0))
for pipe in pipes:
pipe.draw(screen)
base.draw(screen)
bird.draw(screen)
# 显示得分
score_text = font.render(str(score), True, WHITE)
screen.blit(score_text, (SCREEN_WIDTH // 2, 50))
pygame.display.flip()
clock.tick(FPS)
pygame.quit()事件处理:响应关闭窗口、空格键或鼠标点击。
管道生成:每 1.5 秒(90 帧)生成一对管道,移除超出屏幕的管道。
碰撞检测:检查小鸟与管道或边界的碰撞。
绘制:按顺序绘制背景、管道、地面、小鸟和得分。

如果没有地面图片,可用灰色矩形:
pygame.draw.rect(screen, (100, 100, 100), (self.x, self.y, self.width, 100))5. 优化与扩展
5.1 添加开始/结束菜单
在游戏开始前显示“按空格开始”,结束时显示“游戏结束”和最终得分:
game_state = "start"
start_text = font.render("Press SPACE to Start", True, WHITE)
game_over_text = font.render("Game Over", True, WHITE)
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if game_state == "start" and event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
game_state = "playing"
if game_state == "game_over" and event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
bird = Bird()
pipes = []
score = 0
game_state = "playing"
if game_state == "start":
screen.blit(BG_IMG, (0, 0))
screen.blit(start_text, (SCREEN_WIDTH // 2 - 100, SCREEN_HEIGHT // 2))
elif game_state == "playing":
# 此处添加原有游戏循环代码
# 将原代码中 running = False 改为 game_state = "game_over"
# ...
elif game_state == "game_over":
screen.blit(BG_IMG, (0, 0))
screen.blit(game_over_text, (SCREEN_WIDTH // 2 - 80, SCREEN_HEIGHT // 2))
final_score = font.render(f"Score: {score}", True, WHITE)
screen.blit(final_score, (SCREEN_WIDTH // 2 - 50, SCREEN_HEIGHT // 2 + 50))
pygame.display.flip()
5.2 加入音效
添加跳跃、碰撞和得分音效(需要音频文件,如 jump.wav、hit.wav、point.wav):
try:
JUMP_SOUND = pygame.mixer.Sound("assets/jump.wav")
HIT_SOUND = pygame.mixer.Sound("assets/hit.wav")
POINT_SOUND = pygame.mixer.Sound("assets/point.wav")
except FileNotFoundError:
print("音效文件未找到")在对应事件中播放:
# 跳跃时(Bird类)
def jump(self):
self.velocity = JUMP_HEIGHT
JUMP_SOUND.play()
# 得分时(更新管道)
if not pipe.passed and pipe.x < bird.x:
pipe.passed = True
score += 1
POINT_SOUND.play()
# 碰撞时(碰撞检测)
for pipe in pipes:
if bird.rect.colliderect(pipe.top_rect) or bird.rect.colliderect(pipe.bottom_rect):
game_state = "game_over"
HIT_SOUND.play()
if bird.y <= 0 or bird.y >= SCREEN_HEIGHT - 100:
game_state = "game_over"
HIT_SOUND.play()5.3 其他扩展
6. 总结
本教程讲解了如何用 Python 的 Pygame 模块开发一个 Flappy Bird 小游戏。通过这个游戏的开发,可以了解 Pygame 的使用,熟悉游戏开发的逻辑,并对面向对象编程有更深入的理解。
你可以进一步优化代码或尝试开发其他游戏。如果你有想要看的游戏案例,也可以直接告诉我,呼声高的游戏我会优先制作教程。
完整及分步骤代码已上传代码仓库,欢迎下载学习并根据你的创意进行二次开发!
如果教程对你有帮助,请点赞、评论、转发~
你的支持是我坚持更新的动力!
感谢转发和点赞的各位~
本文分享自 Crossin的编程教室 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!