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 游戏对象基类,自带 imagerect 两个核心字段,天然支持碰撞检测。

  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.GroupLayeredUpdates

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

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

六、性能与发布小贴士

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

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

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

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


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

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

相关推荐
GrowingYi1 分钟前
Go语言的特性
开发语言·后端·golang
小尧嵌入式5 分钟前
c++红黑树及B树B+树
开发语言·数据结构·c++·windows·b树·算法·排序算法
Full Stack Developme8 分钟前
Spring Security 与 Apache Shiro 两大安全框架比较
spring boot·python·安全
cike_y8 分钟前
Spring整合Mybatis:dao层
java·开发语言·数据库·spring·mybatis
松涛和鸣12 分钟前
45、无依赖信息查询系统(C语言+SQLite3+HTML)
c语言·开发语言·数据库·单片机·sqlite·html
杰瑞哥哥12 分钟前
快速搭建Web前端(streamlit使用指南)
python·信息可视化·web·模型部署
小途软件13 分钟前
基于计算机视觉的课堂行为编码研究
人工智能·python·深度学习·计算机视觉·语言模型·自然语言处理·django
智航GIS14 分钟前
9.2 多进程入门
数据库·python
小途软件15 分钟前
基于计算机视觉的桥梁索力测试方法
人工智能·python·语言模型·自然语言处理·django
feifeigo12315 分钟前
基于C#实现即时通讯工具
开发语言·c#