本文基于 Windows 环境开发,适合 Python 新手
Python 练手级项目——贪吃蛇
本期介绍 Python 练手级项目——贪吃蛇!
原本想推荐一个贪吃蛇的开源项目:python-console-snake
,但由于该项目最近一次更新是 8 年前,而且在运行的时候出现了诸多问题。索性我就动手用 Python 重新写了一个贪吃蛇游戏。
下面我们就一起用 Python 实现一个简单有趣的命令行贪吃蛇小游戏,启动命令:
git clone https://github.com/AnthonySun256/easy_games
cd easy_games
python snake
本文包含设计和讲解,整体分为两个部分:第一部分是关于 Python 命令行图形化库 curses 接着是 snake 相关代码。
一、初识 curses
Python 已经内置了 curses 库,但是对于 Windows 操作系统我们需要安装一个补丁以进行适配。
Windows 下安装补全包:
pip install windows-curses
curses 是一个应用广泛的图形函数库,可以在终端内绘制简单的用户界面。
在这里我们只进行简单的介绍,只学习贪吃蛇需要的功能
如果您已经接触过 curses,请跳过此部分内容。
1.1 简单使用
Python 内置了 curses 库,其使用方法非常简单,以下脚本可以显示出当前按键对应编号:
# 导入必须的库
import curses
import time
# 初始化命令行界面,返回的 stdscr 为窗口对象,表示命令行界面
stdscr = curses.initscr()
# 使用 noecho 方法关闭命令行回显
curses.noecho()
# 使用 nodelay(True) 方法让 getch 为非阻塞等待(即使没有输入程序也能继续执行)
stdscr.nodelay(True)
while True:
# 清除 stdscr 窗口的内容(清除残留的符号)
stdscr.erase()
# 获取用户输入并放回对应按键的编号
# 非阻塞等待模式下没有输入则返回 -1
key = stdscr.getch()
# 在 stdscr 的第一行第三列显示文字
stdscr.addstr(1, 3, "Hello GitHub.")
# 在 stdscr 的第二行第三列显示文字
stdscr.addstr(2, 3, "Key: %d" % key)
# 刷新窗口,让刚才的 addstr 生效
stdscr.refresh()
# 等待 0.1s 给用户足够反应时间查看文字
time.sleep(0.1)
也可以尝试把 nodelay(True) 改为 nodelay(False) 后再次运行,这时候程序会阻塞在 stdscr.getch() 只有当您按下按键后才会继续执行。
1.2 整点花样
您也许会觉得上面的例子太菜了,随便用几个 print 都能达到相同的效果,现在我们来整点花样以实现一些使用普通输出无法达到的效果。
1.2.1 新建一个子窗口
说再多的话也不如一张图来的实际:
如果我们想要实现图中 Game over! 窗口,可以使用 newwin 方法:
import curses
import time
stdscr = curses.initscr()
curses.noecho()
stdscr.addstr(1, 2, "HelloGitHub")
# 新建窗口,高为 5 宽为 25,在命令行窗口的 四行六列处
new_win = curses.newwin(5, 25, 4, 6)
# 使用阻塞等待模式
new_win.nodelay(False)
# 在新窗口的 2 行 3 列处添加文字
new_win.addstr(2, 3, "www.HelloGitHub.com")
# 给新窗口添加边框,其中边框符号可以这是,这里使用默认字符
new_win.border()
# 刷新窗口
stdscr.refresh()
# 等待字符输入(这里会一直等待输入)
new_win.getch()
# 删除新窗口对象
del new_win
# 清除所有内容(比 erase 更彻底)
stdscr.clear()
# 重新添加文字
stdscr.addstr(1, 2, "HelloGitHub")
# 刷新窗口
stdscr.refresh()
# 等待两秒钟
time.sleep(2)
# 结束 curses 模式,恢复到正常命令行模式
curses.endwin()
除了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()
进行初始化操作:
import curses
import time
stdscr = curses.initscr()
stdscr.nodelay(False)
curses.noecho()
# 初始化彩色模式
curses.start_color()
# 在1号位置添加前景色是绿色,背景色是黑色的彩色对儿
curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLACK)
# 在一行一列处显示文字,使用 1号 色彩搭配
stdscr.addstr(1, 1, "HelloGitHub!", curses.color_pair(1))
# 阻塞等待按键然后结束程序
stdscr.getch()
curses.endwin()
需要注意的是,0号 位置颜色是默认黑白配色,无法修改
1.2.3 给点细节
在此部分最后的最后,我们来说说如何给文字加一点文字效果:
import curses
import time
stdscr = curses.initscr()
stdscr.nodelay(False