用 Python + Pygame 手把手教你做一个小飞鸟游戏(含源码+素材)
本文详细介绍了如何使用 Python 和 Pygame 库开发一个简洁且具有可视化界面的经典小游戏——Flappy Bird。通过完整的项目结构、图像素材管理与游戏逻辑编写,读者将掌握 Pygame 中图像加载、事件响应、碰撞检测与动态渲染等核心知识。项目具备真实的游戏体验,包括小鸟飞行动作、障碍物生成、得分机制与碰撞判定,适合初学者进行图形化编程实战训练。文章同时提供完整源码和素材资源,便于读者
🎮 一、项目介绍
这篇文章将带你用 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
按下 空格键 控制小鸟飞行,挑战更高分数!
更多推荐
所有评论(0)