Python 深入 pygame模块

目录

[一、为什么选择 pygame](#一、为什么选择 pygame)

二、安装与最小骨架

三、像素跑酷:游戏设计说明书

四、代码逐段拆解

五、运行与可扩展方向

六、性能与发布小贴士


一、为什么选择 pygame

在 Python 生态里,「想写游戏」第一时间想到的大多是 pygame。它足够轻量:纯 Python 绑定 SDL,安装一条命令即可;又足够完整:窗口、图像、音频、事件、碰撞检测、时间控制、硬件加速一应俱全。更重要的是,pygame 把「事件循环」这一游戏开发最核心的概念赤裸裸地摆在你面前------学会它,再迁移到 Unity、Godot、Unreal 时就拥有了共同的底层心智模型。


二、安装与最小骨架

python 复制代码
pip install pygame

最小可运行骨架只有 20 行,却包含所有 2D 游戏的生命周期:初始化 → 事件处理 → 更新逻辑 → 渲染 → 帧率控制。

python 复制代码
import pygame, sys
pygame.init()                          # 初始化所有子系统
screen = pygame.display.set_mode((480, 320))
clock = pygame.time.Clock()
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit(); sys.exit()
    screen.fill((30, 30, 30))          # 渲染
    pygame.display.flip()              # 交换缓冲区
    clock.tick(60)                     # 维持 60 FPS

运行后你会看到一个黑色窗口,关闭即退出。骨架有了,接下来让它长出骨骼、肌肉和皮肤。


三、像素跑酷:游戏设计说明书

目标:控制一个像素小人不断向右奔跑,按空格跳跃,避开地面障碍物,得分随存活时间增加。

资源:一张 32×32 的主角图、一张地面图、一张障碍物图,全部使用纯色 Surface 手绘即可,无需外部素材。

核心对象:

  • Player(玩家):受重力影响,支持跳跃;

  • Ground(地面):固定在窗口底部,用于碰撞检测;

  • Obstacle(障碍物):从右侧生成,向左匀速移动;

  • Game(游戏管理器):整合事件循环、生成逻辑、得分渲染。


四、代码逐段拆解

  1. 常量和工具函数
python 复制代码
import pygame, sys, random
pygame.init()
W, H = 480, 320
GROUND_H = 60
GRAVITY = 0.8
JUMP_VEL = -13
SPEED = 5
  1. 玩家类
python 复制代码
class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.Surface((32, 32))
        self.image.fill((255, 209, 102))   # 亮黄色
        self.rect = self.image.get_rect(midbottom=(80, H - GROUND_H))
        self.vel_y = 0
        self.on_ground = True

    def update(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_SPACE] and self.on_ground:
            self.vel_y = JUMP_VEL
            self.on_ground = False

        self.vel_y += GRAVITY
        self.rect.y += self.vel_y
        if self.rect.bottom >= H - GROUND_H:
            self.rect.bottom = H - GROUND_H
            self.vel_y = 0
            self.on_ground = True

Sprite 是 pygame 提供的 2D 游戏对象基类,自带 image 与 rect 两个核心字段,天然支持碰撞检测。

  1. 地面与障碍物
python 复制代码
class Ground(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.Surface((W, GROUND_H))
        self.image.fill((76, 175, 80))
        self.rect = self.image.get_rect(bottomleft=(0, H))

class Obstacle(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        w, h = 40, random.randint(30, 70)
        self.image = pygame.Surface((w, h))
        self.image.fill((239, 83, 80))
        self.rect = self.image.get_rect(midbottom=(W + 20, H - GROUND_H))

    def update(self):
        self.rect.x -= SPEED
        if self.rect.right < 0:
            self.kill()
  1. 游戏主循环
python 复制代码
class Game:
    def __init__(self):
        self.screen = pygame.display.set_mode((W, H))
        pygame.display.set_caption('Pixel Runner')
        self.clock = pygame.time.Clock()
        self.font = pygame.font.SysFont('consolas', 24)
        self.reset()

    def reset(self):
        self.player = Player()
        self.ground = Ground()
        self.obstacles = pygame.sprite.Group()
        self.all_sprites = pygame.sprite.Group(self.player, self.ground)
        self.spawn_timer = 0
        self.score = 0

    def run(self):
        while True:
            self.handle_events()
            self.update()
            self.draw()

    def handle_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit(); sys.exit()

    def update(self):
        self.all_sprites.update()
        self.spawn_timer += 1
        if self.spawn_timer > random.randint(60, 120):
            obstacle = Obstacle()
            self.obstacles.add(obstacle)
            self.all_sprites.add(obstacle)
            self.spawn_timer = 0

        self.score += 1
        if pygame.sprite.spritecollideany(self.player, self.obstacles):
            self.reset()

    def draw(self):
        self.screen.fill((38, 50, 56))
        self.all_sprites.draw(self.screen)
        score_surf = self.font.render(f'Score: {self.score}', True, (255, 255, 255))
        self.screen.blit(score_surf, (10, 10))
        pygame.display.flip()
        self.clock.tick(60)

if __name__ == '__main__':
    Game().run()

五、运行与可扩展方向

把以上代码保存为 runner.py,终端 python runner.py 即可看到黄色小人在绿色地面奔跑,红色障碍物迎面而来。失败时游戏立即重置,得分归零。

你可以继续扩展:

  • 添加背景音乐和跳跃音效,使用 pygame.mixer.Sound;

  • 把纯色 Surface 替换成 PNG 序列帧,实现帧动画;

  • 引入双缓冲 Sprite Sheet 和精灵动画类 pygame.sprite.Group 的 LayeredUpdates;

  • 把障碍物改为"飞行"与"地面"两种,需控制不同碰撞体积;

  • 接入网络模块,做成双人竞速或排行榜系统。

六、性能与发布小贴士

  1. 图片资源优先使用 .convert() 或 .convert_alpha() 减少像素格式转换开销;

  2. 大背景使用 Surface.scroll() 而非逐像素 blit() 实现视差滚动;

  3. 帧率并非越高越好,60 FPS 足够,高帧率会吞噬 CPU 与电池;

  4. 发布时借助 pyinstaller -F runner.py 生成单文件 exe,或使用 nuitka 获得更接近原生的性能。


七、结语:pygame 是游戏开发的"手动挡"

用 pygame 写游戏就像开手动挡汽车:离合器、换挡、油门都要自己踩,却也最能体会驾驶乐趣。当你亲手处理完事件循环、碰撞检测、帧同步,再去拥抱 Unity 的「自动挡」时,会发现那些看似黑盒的组件背后,不过是 pygame 概念的封装与放大。愿这份 2000 字的小跑酷,成为你驶向更广阔游戏世界的起点。

相关推荐
y = xⁿ13 分钟前
关于Agent工程落地
前端·人工智能·python
Evand J18 分钟前
【MATLAB例程】三维快速扩展随机树(RRT)路径规划与到达角(AOA)、到达时间差(TDOA)融合定位,附下载链接
开发语言·matlab·代码·定位·例程
执明wa20 分钟前
Android RecyclerView 实战:点击频道栏切换对应内容
android·开发语言·windows·microsoft·android studio
开开心心就好22 分钟前
图片白底怎么去掉?抠图工具抠完背景透明
java·服务器·开发语言·pdf·ocr·散列表·启发式算法
朝朝辞暮i23 分钟前
C++ 第 22 课:const —— 不允许随便修改的数据
开发语言·c++·算法
web打印社区29 分钟前
JS 静默打印怎么做:纯前端为什么不行,以及最小可跑通写法
开发语言·前端·javascript·websocket·网络协议·http·pdf
大圣编蚕30 分钟前
C语言怎么写小游戏?从零开始做一个贪吃蛇
c语言·开发语言
小小张说故事30 分钟前
pip 安装慢、超时、报错?一份国内源配置 + 9 个高频报错对照表
python
在世修行36 分钟前
干货:长任务反馈
python·长任务
东方芷兰41 分钟前
Agent 技术摘要 05 —— BP、SaaS、B2B、C2B、B2C
java·笔记·python·语言模型·自然语言处理