网易首页 > 网易号 > 正文 申请入驻

保姆级教程!用 Python 写个贪吃蛇

0
分享至

本文基于 Windows 环境开发,适合 Python 新手

HelloGitHub 推出的《讲解开源项目》系列,本期介绍 Python 练手级项目——贪吃蛇!

原本想推荐一个贪吃蛇的开源项目:python-console-snake,但由于该项目最近一次更新是 8 年前,而且在运行的时候出现了诸多问题。索性我就动手用 Python 重新写了一个贪吃蛇游戏。

下面我们就一起用 Python 实现一个简单有趣的命令行贪吃蛇小游戏

本文包含设计和讲解,整体分为两个部分:第一部分是关于 Python 命令行图形化库 curses 接着是 snake 相关代码。

一、初识 curses

Python 已经内置了 curses 库,但是对于 Windows 操作系统我们需要安装一个补丁以进行适配。

Windows 下安装补全包:

pip install windows-curses

curses 是一个应用广泛的图形函数库,可以在终端内绘制简单的用户界面。

在这里我们只进行简单的介绍,只学习贪吃蛇需要的功能

如果您已经接触过 curses,请跳过此部分内容。
1.1 简单使用

Python 内置了 curses 库,其使用方法非常简单,以下脚本可以显示出当前按键对应编号:

您也可以尝试把 nodelay(True) 改为 nodelay(False) 后再次运行,这时候程序会阻塞在 stdscr.getch() 只有当您按下按键后才会继续执行。
1.2 整点花样

您也许会觉得上面的例子太菜了,随便用几个 print 都能达到相同的效果,现在我们来整点花样以实现一些使用普通输出无法达到的效果。

1.2.1 新建一个子窗口

说再多的话也不如一张图来的实际:

如果我们想要实现图中 Game over! 窗口,可以使用 newwin 方法:

除了 curses.newwin 新建一个独立的窗口,我们还能在任意窗口上使用 subwin 或者 subpad 方法新建子窗口,例如 stdscr.subwin、 stdscr.subpad、new_win.subwin、new_win.subpad 等等,其使用方法与本节中创建的 new_win 或者 stdscr 没有区别,只是新建窗口使用独立的缓存区,而子窗口和父窗口共享缓存区。

如果某个窗口会在使用后删除,最好使用 newwin 方法新建独立窗口,以防止删除子窗口造成父窗口的缓存内容出现问题。
1.2.2 上点颜色

白与黑的搭配看久了也会显得单调,curses 提供了内置颜色可以让我们自定义前后背景。

在使用彩色模式之前我们需要先使用使用 curses.start_corlor() 进行初始化操作:

需要注意的是,0号 位置颜色是默认黑白配色,无法修改

1.2.3 给点细节

在此部分最后的最后,我们来说说如何给文字加一点文字效果:

二、贪吃蛇

前面说了这么多,现在终于到了我们的主菜。在这部分,我将一步步教给大家如何从零开始做出一个简单却又不失细节的贪吃蛇。

2.1 设计

对于一个项目来讲,相比于尽快动手写下第一行代码不如先花点时间进行一些必要的设计,毕竟结构决定功能,一个项目没有一个良好的结构是没有前途的。

snake 将贪吃蛇这个游戏分为了三大块:

  1. 界面:负责显示相关的所有工作
  2. 游戏流程控制:判断游戏输赢、游戏初始化等
  3. 蛇和食物:移动自身、判断是否死亡、是否被吃等

每一块都被做成了单独的对象,通过相互配合实现游戏。下面让我们来分别看看应该如何实现。

2.2 蛇语者

对于贪吃蛇游戏里面的蛇来讲,它可以做的事情有三种:移动,死亡(吃到自己,撞墙)和吃东西

围绕着这三个功能,我们可以首先写出一个简陋的蛇,其类图如图所示:

这个蛇可以检查自己是不是死亡,是不是吃了东西,以及更新自己的位置信息。

其中,body 和 last_body 是列表,分别存储当前蛇身坐标和上一步蛇身坐标,默认列表第一个元素是蛇头。direction 是当前行进方向,window_size 是蛇可以活动的区域大小。

rest 方法用于重置蛇的状态,它与 __init__ 共同负责蛇的初始化工作:

Position 是我自定义的类,只有 x, y 两个属性,存储一个坐标点
在最开始我们可能只是模糊的感觉应该有这几个属性,但是对于其中的内容和初始化方法又不完全清楚,这是正常的。我们需要做的就是继续实现需要的功能,在实践中添加和完善最初的构想。

之后,我们从继续上到下实现,对照类图,我们接下来应该实现一下 update_snake_pos 即 更新蛇的位置,这部分非常简单:

其实 last_body 可以只记录最后一次修改的身体,这里我偷了个懒

在这里有一个细节,如果我们是第一次写这个函数,为了让蛇头能够正确地按照玩家操作移动,我们需要知道蛇头元素在 x, y 方向上各移动了多少。

最简单的方法是直接一串 if-elif,判断方向再相加:

但是这样的问题在于,如果我们的需求更改(比如我现在说蛇可以一次走两个格子,或者吃了特殊道具 x, y 方向上走的距离不一样等等)直接修改这样的代码会让人很痛苦。

所以在这里更好的解决办法是使用一个 dis_increment_factor 存储蛇再 x 和 y 上各移动多少,并且新建一个函数 get_dis_inc_factor 进行判断:

当然了,这么做或许有点多余,但是努力做到一个函数只做一件事情能帮助化简我们的代码,降低写出又臭又长还难调试代码的可能性。

解决了移动问题,下一步就是考虑贪吃蛇如何吃到食物了,在这里我们用 check_eat_food 和 eat_food 两个函数完成:

在这里,foods 是一个存储着所有食物位置信息的列表,每次蛇体移动后都会调用 check_eat_food 函数检查是不是吃到了某一个食物。

可以发现,检查是不是「吃到」和「吃下去」这两个动作我分为了两个函数,以做到每个函数「一心一意」方便后期修改。

现在,我们的蛇已经能跑能吃了。但是作为一只能照顾自己的贪吃蛇,我们还需要能够判断当前自身状态,比如最基本的我需要知道我刚刚是不是咬到自己了,只需要看看蛇头是不是移动到了身体里面:

def check_eat_self(self) -> bool:

return self.body[0] in self.body[1:] # 判断蛇头是不是和身体重合

或者我想知道是不是跑得太快而撞了墙:

这些功能都是简单得不能再简单了,但是要相信自己,就是这么简单的几行代码就能实现一个听你指挥能做出复杂动作的

GitHub 完整代码:AnthonySun256/easy_games
2.3 命令行?画板!

上一节中我们实现了游戏里的第一位角色:。为了将它显示出来我们现在需要将我们的命令行改造成一块「画板」。

在动手之前我们同样思考:我们需要画哪些东西在我们的命令行上?直接上类图:

是不是觉得有些眼花缭乱以至于感觉无从下手?其实 Graphic 类方法虽多但是大多数方法只是执行一个特定的功能而已,而且每次更新游戏只需要调用 draw_game 方法即可:

遵循从上到下设计,从下到上实现的原则

可以看出 draw_game 实际上已经完成了 Graphic 的所有功能。

再往下深入,我们可以发现类似 draw_foods、draw_snake_body 实现基本一样,都是遍历坐标列表然后直接在相应位置上添加字符即可:

将其分开实现也是为了保持代码干净易懂以及方便后期修改。draw_help、draw_fps、draw_lives_and_scores 也是分别打印了不同文字信息,没有任何新的花样。

update_fps 实现了帧率的估算以及调节等待时间稳定帧率:

draw_message_window 则实现了绘制胜利、失败的画面:

这样,我们就实现了游戏动画的显示!

2.4 控制!

到目前为止,我们实现了游戏内容绘制以及游戏角色实现,本节我们来学习 snake 的最后一个内容:控制

老规矩,敲代码之前我们应该先想一想:如果要写一个 control 类,它应该都包含哪些方法呢?

仔细思考也不难想到:应该有一个循环,只要没输或者没赢就一直进行游戏,每轮应该更新画面、蛇移动方向等等。这就是我们的 start:

只要我们写出了 start 对于剩下的结构也就能轻松地实现,比如读取按键控制就是最基本的比较数字是不是一样大:

更新蛇的状态时只需要判断是不是死亡、胜利、吃到东西就可:

2.5 直接使用

为了让这个包能够直接使用 python snake 就能直接开始游戏,我们来看一下 __main__.py:

import game

g = game.Game()

g.start()

g.quit()

当我们尝试直接运行一个包时,Python 从 __main__.py 中开始执行,对于我们写好的代码,只需三行即可开始游戏!

三、结尾

到这里如何编写一个贪吃蛇游戏就结束啦!实际上编写一个小游戏不难,对于新手来讲难点在于如何去组织程序的结构。我所实现的只是其中的一种方法,每个人对于游戏结构理解不同所写出的代码也会不同。但无论怎样,我们都应该遵循一个目标:尽量遵循代码规范,养成良好的风格。这样不仅利于别人阅读你的代码,也利于自己排查 bug、增加新的功能。

最后,感谢您的阅读。这里是 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。您的每个点赞、留言、分享都是对我们最大的鼓励!

- END -

HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
谷爱凌爱上币圈诈骗犯孙宇晨?

谷爱凌爱上币圈诈骗犯孙宇晨?

爆角追踪
2026-02-01 17:28:46
跌成白菜价,电视却卖不动了!14亿人干不过3亿美国人,太扎心

跌成白菜价,电视却卖不动了!14亿人干不过3亿美国人,太扎心

阿器谈史
2026-01-31 23:19:36
一觉醒来微信群炸了!腾讯开撒10亿现金红包,已有16人翻出万元奖励“小马卡”!网友:群聊已被刷屏

一觉醒来微信群炸了!腾讯开撒10亿现金红包,已有16人翻出万元奖励“小马卡”!网友:群聊已被刷屏

每日经济新闻
2026-02-01 16:10:05
台湾GDP靓眼   跃居亚洲第三

台湾GDP靓眼 跃居亚洲第三

跟着老李看世界
2026-02-01 11:44:55
“反向春运”火了!部分火车票低至1.9折,南京到上海只要8.5元

“反向春运”火了!部分火车票低至1.9折,南京到上海只要8.5元

上观新闻
2026-02-01 21:39:09
令人发指!前英国王子安德鲁四肢着地跪爬在女子身上!爱泼斯坦文件持续公开,英首相呼吁安德鲁向美国会做证

令人发指!前英国王子安德鲁四肢着地跪爬在女子身上!爱泼斯坦文件持续公开,英首相呼吁安德鲁向美国会做证

纵相新闻
2026-02-01 19:09:12
中国对委内瑞拉下禁令,特朗普一看形势不对,立即向中方发出邀请

中国对委内瑞拉下禁令,特朗普一看形势不对,立即向中方发出邀请

荐史
2026-02-01 18:00:12
卡里克豪取3连胜!英超5战获13分,曼联队史首人,阿莫林下课不冤

卡里克豪取3连胜!英超5战获13分,曼联队史首人,阿莫林下课不冤

奥拜尔
2026-02-02 00:03:35
国外网络基本互通,中国为何限制访问外网?17年前的教训刻骨铭心

国外网络基本互通,中国为何限制访问外网?17年前的教训刻骨铭心

和平声浪
2026-02-01 09:30:41
俄罗斯间谍卫星被毁!马斯克对俄罗斯非法“星链”动手了

俄罗斯间谍卫星被毁!马斯克对俄罗斯非法“星链”动手了

鹰眼Defence
2026-02-01 17:11:51
深圳水贝“杰我睿”最新进展:有消费者收到兑付方案,20g黄金+9000多元余额,兑付本金4856元

深圳水贝“杰我睿”最新进展:有消费者收到兑付方案,20g黄金+9000多元余额,兑付本金4856元

每日经济新闻
2026-02-01 17:45:18
员工刘某一个月内11次长时间滞留卫生间,单日最长达6小时21分钟,被公司解雇,法院:超出合理生理需求,属变相旷工,被解雇合法

员工刘某一个月内11次长时间滞留卫生间,单日最长达6小时21分钟,被公司解雇,法院:超出合理生理需求,属变相旷工,被解雇合法

极目新闻
2026-02-01 09:11:11
2月1日俄乌:马斯克终于出手了

2月1日俄乌:马斯克终于出手了

山河路口
2026-02-01 18:23:05
联赛第二!上海34分狂胜同曦 偰李永炜26+8三分生涯新高

联赛第二!上海34分狂胜同曦 偰李永炜26+8三分生涯新高

醉卧浮生
2026-02-01 21:35:48
杨紫这身材是真实存在的吗,薄薄的一片好瘦呀,极致自律太牛了!

杨紫这身材是真实存在的吗,薄薄的一片好瘦呀,极致自律太牛了!

TVB的四小花
2026-01-31 16:00:58
德约大度祝贺阿卡:未来10年内还会多次相遇!幽默互动逗笑纳达尔

德约大度祝贺阿卡:未来10年内还会多次相遇!幽默互动逗笑纳达尔

我爱英超
2026-02-01 20:37:19
15万个AI建了个朋友圈吐槽人类,100万人围观Moltbook后傻眼了:原来我们对AI一无所知

15万个AI建了个朋友圈吐槽人类,100万人围观Moltbook后傻眼了:原来我们对AI一无所知

AppSo
2026-01-31 20:13:22
以2.5吨白银建造的湖南“永兴银楼”被拍卖,其中1.75吨纯银折算1204.7万元,每克仅6.88元“白菜价”,委托方回应

以2.5吨白银建造的湖南“永兴银楼”被拍卖,其中1.75吨纯银折算1204.7万元,每克仅6.88元“白菜价”,委托方回应

极目新闻
2026-02-01 16:43:12
朝鲜宣布:这是建国以来首次重大决策!

朝鲜宣布:这是建国以来首次重大决策!

IN朝鲜
2026-02-01 15:23:30
突发 | 知名女歌手于文文,被紧急送医!舞台上直接倒地!

突发 | 知名女歌手于文文,被紧急送医!舞台上直接倒地!

天津广播
2026-02-01 22:25:19
2026-02-02 00:31:00
HelloGitHub
HelloGitHub
带你玩GitHub开源社区
190文章数 5242关注度
往期回顾 全部

游戏要闻

《赛博朋克2077》或继续沿用第一人称 主创更喜欢沉浸式

头条要闻

爱泼斯坦追逐女孩、安德鲁跪爬女子身上画面全公布

头条要闻

爱泼斯坦追逐女孩、安德鲁跪爬女子身上画面全公布

体育要闻

德约大度祝贺阿卡 幽默互动逗笑纳达尔

娱乐要闻

春晚第三次联排阵容曝光:全是实力派

财经要闻

黄仁勋台北"夜宴":汇聚近40位台企高管

科技要闻

10亿元宝红包突袭 复刻微信支付还是微视?

汽车要闻

岚图汽车1月交付10515辆 同比增长31%

态度原创

时尚
健康
本地
数码
公开课

“多巴胺风”又又又火了!这样穿时髦又减龄

耳石症分类型,症状大不同

本地新闻

云游中国|拨开云雾,巫山每帧都是航拍大片

数码要闻

极摩客已在海外市场推出新款高端迷你主机NucBox K13

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版