目录
[一、为什么选择 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(游戏管理器):整合事件循环、生成逻辑、得分渲染。
四、代码逐段拆解
- 常量和工具函数
python
import pygame, sys, random
pygame.init()
W, H = 480, 320
GROUND_H = 60
GRAVITY = 0.8
JUMP_VEL = -13
SPEED = 5
- 玩家类
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 两个核心字段,天然支持碰撞检测。
- 地面与障碍物
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()
- 游戏主循环
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; -
把障碍物改为"飞行"与"地面"两种,需控制不同碰撞体积;
-
接入网络模块,做成双人竞速或排行榜系统。
六、性能与发布小贴士
-
图片资源优先使用
.convert()或.convert_alpha()减少像素格式转换开销; -
大背景使用
Surface.scroll()而非逐像素blit()实现视差滚动; -
帧率并非越高越好,60 FPS 足够,高帧率会吞噬 CPU 与电池;
-
发布时借助
pyinstaller -F runner.py生成单文件 exe,或使用nuitka获得更接近原生的性能。
七、结语:pygame 是游戏开发的"手动挡"
用 pygame 写游戏就像开手动挡汽车:离合器、换挡、油门都要自己踩,却也最能体会驾驶乐趣。当你亲手处理完事件循环、碰撞检测、帧同步,再去拥抱 Unity 的「自动挡」时,会发现那些看似黑盒的组件背后,不过是 pygame 概念的封装与放大。愿这份 2000 字的小跑酷,成为你驶向更广阔游戏世界的起点。