🎮 一、项目介绍

这篇文章将带你用 Python 和 Pygame 从零实现一个经典的 Flappy Bird(飞翔的小鸟)小游戏。本项目具备以下特点:

  • 完整实现小鸟飞行控制;

  • 自动生成上下管道障碍;

  • 实时计分机制;

  • 图像资源精美,结构清晰;

  • 源码+素材一键运行!


🗂️ 二、项目结构

你的项目结构如下(使用 PyCharm 或 VS Code 打开):


csharp

复制编辑

flappy_bird/ ├── images/ │ ├── background.png # 背景图 │ ├── base.png # 地面图 │ ├── bird.png # 小鸟图 │ └── pipe.png # 管道图 ├── play.py # 游戏主程序

所有素材来自开源资源:samuelcust/flappy-bird-assets


🐍 三、开发环境

  • Python >= 3.7

  • pygame >= 2.1.0

  • IDE:建议使用 PyCharm / VSCode

安装依赖(终端中):

pip install pygame

✨ 四、游戏界面展示

如下图所示,小鸟可以在空中飞行,通过按空格跳跃,并躲避上下出现的管道,保持不撞击即得分。

📸 项目结构截图:

📸 游戏运行截图:

📜 五、完整源代码 play.py

以下是完整、可运行的 Flappy Bird 游戏主程序(精简优化版):

📎 请将以下代码保存为 play.py

import pygame
import random
import sys

# 初始化 Pygame
pygame.init()

# 设置窗口
WIDTH, HEIGHT = 400, 600
SCREEN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Flappy Bird")
clock = pygame.time.Clock()
FPS = 60

# 加载图像资源
BACKGROUND = pygame.transform.scale(pygame.image.load("images/background.png"), (WIDTH, HEIGHT))
BASE_IMG = pygame.image.load("images/base.png")
BIRD_IMG = pygame.image.load("images/bird.png")
PIPE_IMG = pygame.image.load("images/pipe.png")
PIPE_WIDTH = PIPE_IMG.get_width()

# 字体设置
font = pygame.font.SysFont("Arial", 36)

# 小鸟类
class Bird:
    def __init__(self):
        self.x = 50
        self.y = HEIGHT // 2
        self.gravity = 0.4
        self.lift = -8
        self.velocity = 0
        self.image = BIRD_IMG
        self.rect = self.image.get_rect(center=(self.x, self.y))

    def update(self):
        self.velocity += self.gravity
        self.y += self.velocity
        self.rect.centery = self.y

    def flap(self):
        self.velocity = self.lift

    def draw(self):
        SCREEN.blit(self.image, self.rect)

# 管道类
class Pipe:
    GAP = 150
    SPEED = 3

    def __init__(self, x):
        self.height = random.randint(100, 400)
        self.top_rect = pygame.transform.flip(PIPE_IMG, False, True).get_rect(midbottom=(x, self.height))
        self.bottom_rect = PIPE_IMG.get_rect(midtop=(x, self.height + self.GAP))
        self.passed = False

    def move(self):
        self.top_rect.x -= self.SPEED
        self.bottom_rect.x -= self.SPEED

    def draw(self):
        SCREEN.blit(pygame.transform.flip(PIPE_IMG, False, True), self.top_rect)
        SCREEN.blit(PIPE_IMG, self.bottom_rect)

    def off_screen(self):
        return self.top_rect.right < 0

    def collide(self, bird):
        return bird.rect.colliderect(self.top_rect) or bird.rect.colliderect(self.bottom_rect)

# 地面类
class Base:
    SPEED = 3

    def __init__(self):
        self.image = BASE_IMG
        self.width = self.image.get_width()
        self.x1 = 0
        self.x2 = self.width
        self.y = HEIGHT - self.image.get_height()

    def move(self):
        self.x1 -= self.SPEED
        self.x2 -= self.SPEED
        if self.x1 + self.width < 0:
            self.x1 = self.x2 + self.width
        if self.x2 + self.width < 0:
            self.x2 = self.x1 + self.width

    def draw(self):
        SCREEN.blit(self.image, (self.x1, self.y))
        SCREEN.blit(self.image, (self.x2, self.y))

def draw_window(bird, pipes, base, score):
    SCREEN.blit(BACKGROUND, (0, 0))
    for pipe in pipes:
        pipe.draw()
    base.draw()
    bird.draw()
    text = font.render(f"Score: {score}", True, (255, 255, 255))
    SCREEN.blit(text, (10, 10))
    pygame.display.update()

def main():
    bird = Bird()
    base = Base()
    pipes = [Pipe(WIDTH + 100)]
    score = 0

    running = True
    while running:
        clock.tick(FPS)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
                bird.flap()

        bird.update()
        base.move()

        # 管道处理
        add_pipe = False
        for pipe in pipes:
            pipe.move()
            if pipe.collide(bird):
                running = False
            if not pipe.passed and pipe.top_rect.right < bird.rect.left:
                pipe.passed = True
                add_pipe = True
                score += 1
        if add_pipe:
            pipes.append(Pipe(WIDTH + 100))
        pipes = [p for p in pipes if not p.off_screen()]

        # 碰撞检测
        if bird.y >= HEIGHT - base.image.get_height() or bird.y <= 0:
            running = False

        draw_window(bird, pipes, base, score)

    pygame.time.delay(1500)
    main()  # 游戏结束后自动重新开始(可修改为显示菜单)

if __name__ == "__main__":
    main()

✅ 六、运行方法

确保目录结构无误后,在项目根目录下运行:

python play.py

按下 空格键 控制小鸟飞行,挑战更高分数!

参考链接:https://www.documents.newoxygenit.tech/article/aaa

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐