简介:这份Pygame教程面向已掌握Python基础、希望入门2D游戏开发的初学者与自学者,系统讲解游戏主循环、Surface对象、Event事件、Rect区域等核心概念,帮助读者从零搭建可运行的小游戏。教程以知识点配合示例的方式组织,覆盖Display显示、Transform图像变形、Time时间控制、Draw绘图函数、Font文本字体以及精灵与碰撞检测等模块,并穿插飞机大战、贪吃蛇、扫雷等典型场景,便于边学边练、理解各模块的协作方式。资源包为1个PDF文件,大小约1.32MB,单文件结构完整,适合打印或分章节阅读。目前已有1568人学习,说明内容经过一定规模读者的检验。对于想以Pygame作为游戏开发敲门砖的读者,可从中获得清晰的知识脉络、可复用的示例代码思路与模块化开发习惯,为后续独立完成2D小游戏打下基础。
1. 零基础也能玩:Pygame 到底是什么,为什么值得你花一个周末
很多人第一次听到「游戏开发」,脑子里浮现的是几十人团队、几千万预算、满屏看不懂的引擎界面,于是还没开始就先把自己劝退了。其实你可以换个角度想:游戏开发就像搭乐高,先有一块底板,再往上拼小方块。Pygame 就是 Python 世界里那块最便宜的底板——它不逼你学新语言,不逼你装几个 G 的引擎,你只要会一点点 Python,就能让一个窗口弹出来、让一个方块动起来。
Pygame 是 Python 的一个第三方游戏开发模块,专门用来做 2D 小游戏,比如贪吃蛇、飞机大战、扫雷这类你小时候玩过的东西。它免费、开源,Windows、Linux、Mac 都能跑,底层封装了一套跨平台的多媒体库,把图像、声音、键盘鼠标这些琐碎活儿都替你处理好了。对零基础新手来说,它最大的价值不是「能做多大项目」,而是「能让你在半小时内看到自己写的东西动起来」——这种即时反馈,是坚持学下去的关键。这份 Pygame 课程资源把安装、窗口、Surface、事件、绘图、字体、精灵碰撞都串成了一条线,适合完全没碰过图形编程、但想亲手做出第一个小游戏的人。
2. 先想清楚再动手:为什么新手第一站选 Pygame 而不是别的
2.1 它把「游戏开发」拆成了你能一口一口吃的小块
刚接触游戏开发的人最容易犯的错,是一上来就盯着 3D 引擎或者大型商业引擎看,结果被材质、光照、物理系统这些词砸晕。Pygame 的思路完全相反:它只给你最基础的三样东西——一张画布(窗口)、一堆可以往上贴的图片或文字(Surface)、一个不停转的循环(游戏主循环)。你不需要理解渲染管线,也不需要懂着色器,只要知道「每秒钟把画面重画几十次,人眼就觉得它在动」,就已经摸到游戏开发的门槛了。
这份教程的编排也是这个逻辑:先让你把窗口开出来,再往窗口里填颜色、贴文字、贴图片,然后教你怎么监听键盘鼠标,最后才讲到精灵和碰撞检测。每一步都只比上一步多一点点,不会出现「前面还没懂、后面已经飞起」的情况。我第一次学的时候,就是卡在「为什么要有主循环」这件事上,后来想明白了:游戏和普通脚本不一样,普通脚本跑完就结束,游戏得一直等着你操作,所以必须有一个死循环在那儿转,一边收事件、一边更新画面。
2.2 会 Python 就够,前置知识门槛低到几乎不存在
教程里写得很直白:适合有一定 Python 基础的人。什么叫「一定基础」?你能写个 for 循环、知道什么是列表和字典、能看懂函数调用,就够了。不需要你会面向对象,不需要你懂多线程,更不需要你碰过任何图形库。如果你连 Python 都还没装,那建议先花半天把 Python 装好、跑通一个print("hello"),再回来接着看,这一步绕不过去,但也就半天的事。
对比一下其他选择:想做 3D 可以去了解 Panda3D 这类库,但那些东西的学习曲线陡得多,而且 Python 本身并不擅长大型 3D 项目;想走职业游戏开发路线,后面确实要补 C++、C# 和商业引擎,但那是以后的事。入门阶段最怕的就是「选了一个太重的工具,还没尝到甜头就被劝退」。Pygame 轻、快、反馈直接,拿来当敲门砖刚刚好。
2.3 装起来不折腾,一条命令就能验证成功
安装这件事,教程给了两条路:pip 安装和二进制包安装。强烈建议走 pip,因为它是 Python 自带的包管理器,最省心。打开命令行(Windows 是 cmd,Mac 和 Linux 是终端),敲下面这行:
# 用 pip 安装 pygame,这是最轻量、最推荐的方式 pip install pygame敲完等它跑完,看到 Successfully installed 字样就说明装上了。然后验证一下版本,确认不是装了个寂寞:
# 查看当前安装的 pygame 版本,能打印出版本号就说明安装成功 python -m pygame --version如果这条命令报错说找不到 pygame,大概率是 pip 装到了另一个 Python 环境里,这时候别慌,先python --version看看当前用的是哪个 Python,再用python -m pip install pygame重装一遍,让 pip 和 python 指向同一个解释器。这个坑我踩过不止一次,血泪经验就是:装库之前先确认自己在哪个环境里。
提示:教程里提到的二进制安装包方式也能用,但对新手来说多了一步下载和切目录的操作,除非 pip 实在装不上,否则不用折腾。
3. 第一个程序别怕:从开窗口到让文字显示出来
3.1 五行代码开出一个窗口,先建立「我能控制它」的信心
很多人卡在第一步,是因为一上来就看完整示例,几十行代码铺面而来,直接懵。我们把它拆开。先只做一件事:开一个窗口,让它停在那儿别闪退。
import sys import pygame # 使用 pygame 的任何功能之前,必须先初始化 pygame.init() # 创建一个 400x400 的主窗口,这个窗口就是后面所有内容的画布 screen = pygame.display.set_mode((400, 400)) # 给窗口起个名字,显示在标题栏上 pygame.display.set_caption('我的第一个窗口') # 主循环:让窗口一直开着,直到用户点关闭 while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() # 把画好的内容刷新到屏幕上 pygame.display.flip()逐行解释一下。pygame.init()是开机自检,把显示、字体、声音这些模块都唤醒,漏了它后面全白搭。set_mode((400, 400))里的元组是宽和高,单位是像素,返回的screen本质上就是一张大画布。while True是游戏主循环,它干三件事:收事件、更新状态、刷新画面。pygame.event.get()把这一帧里发生的所有操作(点关闭、按键、动鼠标)都捞出来,你逐个判断。pygame.QUIT就是点了右上角那个叉,收到它就清理退出。最后的flip()是把内存里画好的东西真正推到屏幕上,没有它你看到的可能是一片黑。
跑起来之后,你应该能看到一个灰黑色的空窗口。别小看这一步,能开出窗口,说明环境、初始化、主循环这条链路全通了,后面只是往这张画布上加东西而已。
3.2 往窗口里贴文字:理解 Surface 这个核心概念
窗口有了,接下来往里放点内容。Pygame 里所有能显示的东西——文字、图片、色块——本质上都是 Surface,你可以把它理解成一张张透明或不透明的小纸片,最后用blit()把这些纸片贴到大画布上。
import sys import pygame pygame.init() screen = pygame.display.set_mode((400, 400)) pygame.display.set_caption('显示文字') # 加载一个系统字体,50 是字号;这里用黑体,路径按自己系统改 font = pygame.font.Font('C:/Windows/Fonts/simhei.ttf', 50) # 把文字渲染成一张 Surface:内容、是否平滑、文字颜色、背景颜色 text = font.render('你好 Pygame', True, (255, 0, 0), (0, 0, 0)) # 拿到这张文字纸片的矩形区域,用来定位 text_rect = text.get_rect() # 把它的中心点设到窗口中心 (200, 200) text_rect.center = (200, 200) while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() # 先把文字纸片贴到画布上,再刷新 screen.blit(text, text_rect) pygame.display.flip()这里的关键是font.render()的四个参数:第一个是文字内容,第二个 True 表示开启抗锯齿(字边缘更平滑),第三个是文字颜色 RGB,第四个是背景色 RGB。返回的text是一张 Surface,get_rect()拿到它的位置和尺寸信息,center一设就居中了。blit(text, text_rect)就是「把这张纸片贴到画布的指定位置」。
注意字体路径:Windows 下黑体一般在C:/Windows/Fonts/simhei.ttf,Mac 和 Linux 路径不一样,找不到就换成系统里存在的字体文件,或者用pygame.font.SysFont('simhei', 50)让 Pygame 自己去系统字体里找。这一步翻车的人特别多,现象就是报错说找不到文件,原因就是路径写死了但系统里没有,换成 SysFont 或者改成自己机器上真实存在的字体路径就行。
3.3 让画面动起来:主循环里加一个会变的数
静态文字贴上去之后,你可能会问:游戏里的东西是怎么动起来的?答案朴素得有点可爱——每帧把位置改一点点,然后重画。下面让一个方块从左往右跑。
import sys import pygame pygame.init() screen = pygame.display.set_mode((400, 300)) pygame.display.set_caption('会动的方块') # 方块的初始横坐标 x = 0 while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() # 每帧把横坐标加 1,方块就向右移动 x += 1 # 跑出右边界就回到左边,形成循环 if x > 400: x = 0 # 每帧先用背景色把上一帧擦掉,否则会留下拖影 screen.fill((30, 30, 30)) # 在当前位置画一个 50x50 的红色方块 pygame.draw.rect(screen, (255, 0, 0), (x, 125, 50, 50)) pygame.display.flip()screen.fill()这一句是新手最容易漏的,漏了会看到方块拖出一条长长的尾巴,因为上一帧的画没被擦掉。pygame.draw.rect()的四个参数分别是画布、颜色、矩形区域(左上角 x、左上角 y、宽、高)。每帧 x 加 1,方块就一像素一像素往右挪,循环一秒钟跑几十次,看起来就是平滑移动。这就是游戏动画最底层的逻辑,后面所有复杂效果都是在这个骨架上长出来的。
4. 把交互接上:事件、时间与画面刷新,一个都不能少
4.1 事件监听:让键盘和鼠标真正「有反应」
游戏和视频的区别在于,游戏会回应你。Pygame 把所有输入都包装成事件,统一从pygame.event.get()里取。除了关闭窗口的 QUIT,最常用的就是键盘和鼠标。
import sys import pygame pygame.init() screen = pygame.display.set_mode((400, 300)) pygame.display.set_caption('键盘与鼠标') while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() # 按下键盘时触发,event.key 是具体哪个键 elif event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: print('你按下了空格') # 鼠标按下时触发,event.pos 是点击坐标 elif event.type == pygame.MOUSEBUTTONDOWN: print('鼠标点在', event.pos) screen.fill((30, 30, 30)) pygame.display.flip()KEYDOWN是按下那一刻触发一次,event.key告诉你按的是哪个键,pygame.K_SPACE这类常量把键名变成了可读的写法。鼠标的MOUSEBUTTONDOWN同理,event.pos是一个 (x, y) 元组。这里有个容易混淆的点:KEYDOWN和KEYUP是分开的,按住不放不会一直触发 KEYDOWN,想实现「按住持续移动」得在循环外查pygame.key.get_pressed(),而不是靠事件。这个区别新手经常搞混,现象是按住方向键人物只动一下,原因就是只监听了按下事件。
4.2 时间控制:FPS 决定了你的游戏是流畅还是卡成 PPT
上面那个方块例子有个隐患:它跑多快完全取决于你电脑的性能,快机器上飞一样,慢机器上像蜗牛。游戏里得把速度钉死,靠的就是时钟对象。
import sys import pygame pygame.init() screen = pygame.display.set_mode((400, 300)) pygame.display.set_caption('控制帧率') # 创建一个时钟对象,用来管理帧率 clock = pygame.time.Clock() x = 0 while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() x += 2 if x > 400: x = 0 screen.fill((30, 30, 30)) pygame.draw.rect(screen, (255, 0, 0), (x, 125, 50, 50)) pygame.display.flip() # 限制每秒最多 60 帧,多出来的时间就等着 clock.tick(60)clock.tick(60)的意思是「这一帧最多花 1/60 秒,没花完就等一等」。它让游戏在所有机器上速度一致,也顺便降低了 CPU 占用。教程里提到一般人能接受的最低帧率大概 30,想要流畅最好 60 以上,这个数字记住就行。另外pygame.time.wait(3000)可以让程序暂停 3 秒,单位是毫秒,做开场动画或者简单延时的时候能用上,但它会卡住整个程序,别在主循环里乱用。
4.3 刷新方式:flip 和 update 到底该用哪个
每帧画完都得告诉 Pygame「可以显示了」,这里有两个方法:pygame.display.flip()和pygame.display.update()。前者刷新整个窗口,后者可以只刷新你指定的区域。新手阶段无脑用 flip 就行,简单不出错;等你以后做复杂画面、想省性能的时候,再考虑用 update 传一个矩形区域进去,只重画变化的部分。教程里也说了,update 不传参数时效果和 flip 一样,所以先记住 flip,别在这上面纠结太久。
5. 新手最容易翻车的几个地方:避坑与排查
5.1 窗口一闪而过,什么都没看到
现象:运行程序,黑窗口闪一下就没了。原因:主循环没写,或者循环里没有pygame.event.get()导致事件队列堵死。解决:确认while True存在,并且循环体里一定有事件遍历和pygame.display.flip(),两者缺一不可。很多人只写了画图没写刷新,或者只写了循环没处理 QUIT,都会出各种怪现象。
5.2 中文显示成方块或者直接报错
现象:font.render()出来的中文是一堆方框,或者直接抛异常说字体文件找不到。原因:字体路径写死成了别人机器上的路径,或者选的字体不含中文字形。解决:优先用pygame.font.SysFont('simhei', 50)让系统自己找,或者把字体文件复制到项目目录下用相对路径加载。路径里尽量别带中文和空格,这也是个老生常谈的坑。
5.3 画面拖影,方块后面跟了一串影子
现象:移动的物体后面拖着残影。原因:每帧没有用背景色清屏,上一帧的内容还留在画布上。解决:在画新内容之前先screen.fill(背景色),把整张画布擦干净再画。这个顺序不能反,先画后擦等于白画。
5.4 装了 pygame 但 import 报 ModuleNotFoundError
现象:命令行里pip install pygame显示成功,代码里import pygame还是报找不到。原因:pip 和当前运行代码的 Python 不是同一个环境,常见于电脑上装了多个 Python 版本。解决:用python -m pip install pygame重装,确保 pip 挂在当前解释器下;或者用python -m pygame --version先确认这个 Python 到底认不认 pygame。
5.5 事件写了但没反应,按键像石沉大海
现象:明明写了 KEYDOWN 判断,按键盘就是没输出。原因:事件判断写在了主循环外面,或者窗口没有获得焦点。解决:所有事件处理必须放在while True里面的for event in pygame.event.get()里;另外点一下游戏窗口让它获得焦点再按键,这个细节听起来傻,但真有人栽在上面。
6. 学完这些下一步往哪走:一条不绕弯的练习路线
走到这里,你已经能把窗口开出来、把文字和图形贴上去、让方块动起来、接上键盘鼠标、控制住帧率,这已经是 Pygame 最核心的骨架了。接下来别急着去看那些大而全的项目,按下面这条路线练,每一步都小到当天能做完。
| 阶段 | 练什么 | 用到的知识点 | 大概耗时 |
|---|---|---|---|
| 第一步 | 用方向键控制一个方块上下左右移动 | 事件监听、坐标更新、边界判断 | 半天 |
| 第二步 | 做一个能移动的挡板加一个弹跳的小球 | Rect 碰撞检测、速度变量 | 一天 |
| 第三步 | 给小球加上得分文字,碰壁就加分 | 字体渲染、分数变量 | 半天 |
| 第四步 | 把方块换成图片,加上背景图 | image.load、convert、blit | 一天 |
| 第五步 | 做一个完整的打砖块或贪吃蛇 | 精灵、碰撞、游戏状态管理 | 两到三天 |
这张表里的顺序是有讲究的:先练「控制」,再练「碰撞」,再练「界面信息」,最后才碰图片和完整项目。每一步都只引入一两个新概念,不会让你同时面对一堆陌生东西。我自己当初就是跳过了第二步直接去做完整游戏,结果碰撞检测写得一团糟,回头补课反而更费时间,这个亏吃一次就够了。
再往后,教程里提到的精灵(Sprite)和碰撞检测值得重点看,它们是组织游戏对象的正规做法,比手动管理一堆坐标变量清爽得多。等你把打砖块或者贪吃蛇完整做出来一个,再回头看 Surface、Rect、事件这些概念,会发现它们已经长在你脑子里了。到那时候,你可以去翻翻 Pygame 官方示例,看看别人怎么组织代码,也可以尝试给游戏加音效、加开始界面、加暂停功能,这些都是很自然的延伸。
最后说个习惯:从那以后我每次写 Pygame 程序,都强制自己先把「初始化、开窗口、主循环、退出处理」这四件套敲完跑通,再往里加任何新东西。这个骨架稳了,后面加什么都不会崩;骨架不稳,加什么都是在沙子上盖楼。希望这份资源能帮你把第一步迈出去,剩下的就是动手了。
本文还有配套的精品资源,点击获取