Pygame实战(一)

Python 实战:用 Pygame 从零做一个 Flappy Bird(详细版)

前言

这是一节面向初学者的 Python 实战课,带大家用 Pygame 从零实现一个 Flappy Bird 小游戏。

本篇会详细讲清楚每一步的原理,包括环境准备、游戏循环、面向对象的结构、精灵的定位方式。看完本篇,你能理解游戏是怎么跑起来的,以及每一行代码在做什么。


一、认识 pip 和 pip3

pip 是什么

pip 是 Python 的包管理器,可以理解成 Python 的"应用商店"。

Python 自带了很多标准库(比如 mathrandom),直接 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:pippip3 一般是同一个。
  • 电脑同时装了 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 安装包

  1. 去 python.org 下载对应版本安装包
  2. 双击打开,选择 Modify
  3. 勾选 pip 和 Add Python to environment variables
  4. 一路 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

即可自动创建虚拟环境。


三、最小演示:让窗口出现,并且能关闭

先不建正式项目,直接写一段最简单的代码,亲眼看看窗口是怎么出来的。

为什么游戏一定要有一个循环

电影是静止画面一张一张连续播放,才动起来的。游戏也一样,每一帧要做三件事:

  1. 检查玩家有没有操作(键盘、鼠标、关闭按钮)
  2. 更新游戏里的数据(位置、速度、得分)
  3. 把最新的画面画出来

如果只画一次,窗口会一闪而过。所以必须用一个 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_eventsupdatedraw
  • 以后所有功能都往这三个方法里加,结构非常清晰。
  • 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

360640(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 的关系)。

posted on 2026-09-14 00:16  凌晨码字  阅读(4)  评论(0)    收藏  举报