Pygame实战(一)
Python 实战:用 Pygame 从零做一个 Flappy Bird(详细版)
前言
这是一节面向初学者的 Python 实战课,带大家用 Pygame 从零实现一个 Flappy Bird 小游戏。
本篇会详细讲清楚每一步的原理,包括环境准备、游戏循环、面向对象的结构、精灵的定位方式。看完本篇,你能理解游戏是怎么跑起来的,以及每一行代码在做什么。
一、认识 pip 和 pip3
pip 是什么
pip 是 Python 的包管理器,可以理解成 Python 的"应用商店"。
Python 自带了很多标准库(比如 math、random),直接 import 就能用。
但像 pygame 这种第三方库,需要额外安装。pip 就是干这个的。
常用命令:
pip install pygame # 安装
pip list # 查看已安装的包
pip uninstall pygame # 卸载
pip 和 pip3 的区别
pip:Python 2 时代沿用下来的命令,有些系统里它也指向 Python 3。pip3:明确指定这是给 Python 3 用的 pip。
因为 Python 2 早已停止维护,现在几乎都用 Python 3。所以:
- 电脑只装了 Python 3:
pip和pip3一般是同一个。 - 电脑同时装了 Python 2 和 3:
pip可能指向 Python 2,pip3才指向 Python 3。
最保险的写法是用模块方式调用:
python -m pip install pygame
意思是"用当前这个 python 解释器自带的 pip 装包",可以避免版本对不上的问题。
如何检查是否安装了 pip
在终端输入:
pip --version
如果看到类似下面的输出,说明装好了:
pip 23.3.1 from ... (python 3.11)
如果提示"pip 不是内部或外部命令",那就是没装或者没加进环境变量。
没有 pip 怎么装
方法一:重新运行 Python 安装包
- 去 python.org 下载对应版本安装包
- 双击打开,选择 Modify
- 勾选 pip 和 Add Python to environment variables
- 一路 Next 完成
方法二:用 Python 自带的 ensurepip
python -m ensurepip --upgrade
方法三(Mac/Linux):
# Ubuntu / Debian
sudo apt install python3-pip
# Mac
brew install python
在 PyCharm 中用 pip
在 PyCharm 里创建项目后,打开底部的 Terminal,提示符前会有一个 (venv),说明当前处在虚拟环境里,此时:
pip install pygame
就只会装到当前项目,不会污染全局环境。
二、PyCharm 虚拟环境的优势
每个项目可能依赖不同版本的库,如果都装到全局环境里会互相冲突。
虚拟环境为每个项目创建一份独立的 Python 环境:
- 依赖互不干扰
- 打包 exe 时只会打包当前环境的依赖,体积更小
- 换电脑时导出
requirements.txt就能复现环境
在 PyCharm 里新建项目时选择:
New environment using Virtualenv
即可自动创建虚拟环境。
三、最小演示:让窗口出现,并且能关闭
先不建正式项目,直接写一段最简单的代码,亲眼看看窗口是怎么出来的。
为什么游戏一定要有一个循环
电影是静止画面一张一张连续播放,才动起来的。游戏也一样,每一帧要做三件事:
- 检查玩家有没有操作(键盘、鼠标、关闭按钮)
- 更新游戏里的数据(位置、速度、得分)
- 把最新的画面画出来
如果只画一次,窗口会一闪而过。所以必须用一个 while 循环不断重复这三件事。
这就是游戏引擎的核心:循环。
最小演示代码
新建一个 main.py,写入:
import pygame
import sys
pygame.init()
screen = pygame.display.set_mode((360, 640))
pygame.display.set_caption("最小演示")
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
screen.fill((135, 206, 235))
pygame.display.flip()
逐行讲解
import pygame
导入 pygame 库。
import sys
Python 标准库,用来彻底退出程序。
pygame.init()
初始化 pygame 的所有子模块。不写这句,后面的窗口创建会报错。
screen = pygame.display.set_mode((360, 640))
创建窗口,宽 360,高 640。这是常见的手机竖屏比例。
返回值 screen 是一个 Surface 对象,可以理解为"整块画布"。
pygame.display.set_caption("最小演示")
设置窗口标题栏文字。
while True:
游戏循环。没有它,程序画完一帧就结束了。
for event in pygame.event.get():
取出这一帧发生的所有事件,逐个处理。
if event.type == pygame.QUIT:
pygame.QUIT 表示用户点了窗口右上角的 X。不处理它,就关不掉窗口。
pygame.quit() 与 sys.exit()
pygame.quit() 卸载 pygame 模块,释放资源。
sys.exit() 真正结束 Python 程序。
screen.fill((135, 206, 235))
用天蓝色填充整块画布。RGB 颜色,每个通道 0~255。
pygame.display.flip()
把后台画好的内容翻到屏幕前面,之前画的都还看不见。
运行效果
弹出一个 360×640 的天蓝色窗口,标题"最小演示",点 X 能关闭。
这就是所有游戏的最基本骨架。
四、正式用面向对象的方式开始
演示代码只是让大家看到窗口和循环。正式项目要更清晰,我们用面向对象的方式来组织。
项目结构:
flappy_bird/
├── main.py # 入口,只有几行
├── screen.py # Game 类,管理整个游戏
└── tool.py # 存放所有常量
五、第一步:写 Game 类
在 screen.py 里定义一个 Game 类,把游戏循环封装进去。
import pygame
import sys
class Game:
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((360, 640))
pygame.display.set_caption("Flappy Bird 精灵版")
self.clock = pygame.time.Clock()
self.running = True
def handle_events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
def update(self):
pass
def draw(self):
self.screen.fill((135, 206, 235))
pygame.display.flip()
def run(self):
while self.running:
self.handle_events()
self.update()
self.draw()
self.clock.tick(60)
pygame.quit()
sys.exit()
讲解
- 整个游戏被封装成一个 Game 类。
- 游戏循环的三件事被拆成三个方法:
handle_events、update、draw。 - 以后所有功能都往这三个方法里加,结构非常清晰。
- 用
self.running控制循环,比while True更优雅。点 X 后running = False,循环自然结束,再统一清理资源。 self.clock.tick(60)把帧率限制在 60。不加这句,电脑有多快跑多快,会烧 CPU。
六、第二步:写入口 main.py
from screen import Game
if __name__ == "__main__":
game = Game()
game.run()
讲解
from screen import Game:从screen.py里导入 Game 类。if __name__ == "__main__"::Python 入口文件的写法。意思是"只有直接运行这个文件时才执行下面的代码",被 import 时不会自动跑。game = Game()创建游戏对象,game.run()让它跑起来。
七、第三步:把常量搬到 tool.py
360、640、(135, 206, 235) 这些数字写死在 screen.py 里,以后想改窗口大小或颜色,得翻遍代码。建一个 tool.py 专门存放常量。
WIDTH = 360
HEIGHT = 640
FPS = 60
SKY_COLOR = (135, 206, 235)
screen.py 里所有硬编码数字换成 tool.XXX:
import pygame
import sys
import tool
class Game:
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((tool.WIDTH, tool.HEIGHT))
pygame.display.set_caption("Flappy Bird 精灵版")
self.clock = pygame.time.Clock()
self.running = True
def handle_events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
def update(self):
pass
def draw(self):
self.screen.fill(tool.SKY_COLOR)
pygame.display.flip()
def run(self):
while self.running:
self.handle_events()
self.update()
self.draw()
self.clock.tick(tool.FPS)
pygame.quit()
sys.exit()
想改成 480×854,只改 tool.py 一行。
八、关于屏幕尺寸
普通手机竖屏比例大约是 9:16。常见分辨率有:
- 360×640
- 375×667
- 414×896
我们选 360×640,数字圆整、计算方便,看起来像手机小游戏。
九、关于"图形是怎么来的"
接下来要往窗口上画小鸟、管道。这些图形从哪来?
两种方式
方式一:用代码画(本次课程使用)
image = pygame.Surface((30, 30)) # 创建一块 30x30 的画布
image.fill((255, 255, 0)) # 填满黄色
# 现在 image 就是一张"黄色图片"
方式二:加载图片(拓展,本次不讲)
image = pygame.image.load("image/bird.png").convert_alpha()
以后只需要把 pygame.Surface 替换成 pygame.image.load,其他代码完全不用动。
关键:image 和 rect
不管图形是画的还是加载的,每个精灵都有两个核心属性:
image:一张 Surface,表示"显示什么"rect:一个 Rect,表示"显示在哪、多大"
两者独立:image 决定外观,rect 决定位置和碰撞范围。这是 Pygame 定位的核心思想。
十、最终文件汇总
tool.py
WIDTH = 360
HEIGHT = 640
FPS = 60
SKY_COLOR = (135, 206, 235)
screen.py
import pygame
import sys
import tool
class Game:
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((tool.WIDTH, tool.HEIGHT))
pygame.display.set_caption("Flappy Bird 精灵版")
self.clock = pygame.time.Clock()
self.running = True
def handle_events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
def update(self):
pass
def draw(self):
self.screen.fill(tool.SKY_COLOR)
pygame.display.flip()
def run(self):
while self.running:
self.handle_events()
self.update()
self.draw()
self.clock.tick(tool.FPS)
pygame.quit()
sys.exit()
main.py
from screen import Game
if __name__ == "__main__":
game = Game()
game.run()
十一、小结
- 认识了 pip 与 pip3 的区别,学会安装 pip 和 pygame
- 了解了 PyCharm 虚拟环境的好处
- 用最小代码看到了游戏循环、窗口和关闭按钮
- 用面向对象的方式创建了项目骨架:
Game类 +main入口 +tool常量
运行 main.py,看到一个 360×640 的天蓝色窗口,点 X 能关闭,第一步就完成了。
下一篇会往 screen.py 里加入小鸟精灵,重点讲 Pygame 的定位方式(image 和 rect 的关系)。
浙公网安备 33010602011771号