【Python贪吃蛇】:编码技巧与游戏设计的完美结合
文章目录
- 🔥一、运行效果
- 💥二、游戏教程
- ✈1. 导入模块
- ❤️2. 初始化游戏元素
- ☔3. 改变蛇移动的方向
- 👊4. 绘制方块
- 🚀5. 检查蛇头是否在游戏区域内
- 🌈6. 定义蛇的移动函数
- 🎬7. 绑定键盘事件
- ⭐三、完整代码
🔥一、运行效果
Python实现贪吃蛇
💥二、游戏教程
🚲turtle模块
Python的turtle模块是一个非常基础的绘图库,它允许用户创建一个画布并在上面绘制图形。这个模块通常用于教学目的,特别是适合初学者学习编程和理解基本的图形概念。
turtle的一些关键特性:
- 画布和乌龟:turtle模块提供了一个名为“乌龟”的画笔,可以在一个名为“画布”的窗口上绘制图形。用户可以控制乌龟的移动来画出各种图案。
- 前进和后退:可以使用forward()和backward()方法让乌龟在画布上前进或后退。
- 转向:left()和right()方法可以让乌龟左转或右转,可以通过度数参数指定转向的角度。
- 抬笔和落笔:penup()和pendown()方法分别用于抬起和放下乌龟的笔,抬起笔时乌龟移动不会绘制线条,而放下笔时会绘制线条。
- 颜色和填充:可以设置乌龟绘制的颜色,并且可以填充封闭图形的内部。
- 速度控制:可以设置乌龟的移动速度,从最快到最慢。
- 监听事件:turtle模块可以监听键盘和鼠标事件,这使得它可以用来创建简单的交互式图形应用。
- 设置画布:可以设置画布的大小、背景颜色等。
- 坐标系统:turtle模块使用笛卡尔坐标系,原点在画布的中心,x轴向右,y轴向上。
- 子图和窗口:可以在一个窗口中创建多个乌龟对象,或者在多个窗口中绘图。
- 更新和动画:通过update()方法可以刷新画布显示,实现动画效果。
- 事件循环:turtle模块提供了事件循环,允许程序保持运行状态直到用户关闭窗口。
turtle模块非常适合用来创建游戏、绘制复杂的几何图形,或者作为教授编程逻辑和控制结构的工具。
✈1. 导入模块
import turtle
import copy
from random import randrange
- turtle:用于绘制图形和动画。
- copy:用于复制蛇的头部坐标,避免在移动蛇时直接修改原始列表。
- randrange:从random模块中导入,用于生成随机数,这里用来随机放置食物。
❤️2. 初始化游戏元素
创建画布和设置标题
wn = turtle.Screen()
wn.title('贪吃蛇游戏')
保持打开绘图窗口
# 不让屏幕立马消失
turtle.done()
turtle.done()是一个非常重要的函数,它用于结束绘图操作并保持打开绘图窗口,直到用户关闭该窗口。这允许用户观察绘制的图形,而不会因为程序的结束而丢失绘图结果。
使用场景
在绘制图形或动画的最后,你会调用turtle.done()来结束你的绘图脚本。例如,在绘制完一个图形或完成一个动画循环后,你可以使用它来防止程序立即退出,从而让用户有足够的时间来查看结果。

注意事项
- 如果在调用turtle.done()之前程序崩溃或被强制终止,绘图窗口可能会立即关闭。
- 在某些IDE(如Jupyter Notebook)中,turtle.done()可能不会按预期工作,因为这些环境可能不支持turtle模块的图形窗口特性。
设置蛇的长度
snake = [[0, 0], [0, 10], [0, 20]]
这里初始化了蛇的三个部分,每个部分由一个列表表示,列表包含两个元素,分别代表蛇的x和y坐标。在这个例子中,蛇有三个部分,初始位置分别是(0, 0)、(0, 10)和(0, 20)。
蛇移动的方向
aim = [0, 10]
aim列表定义了蛇的移动方向,其中第一个元素是水平方向(向右为正,向左为负),第二个元素是垂直方向(向下为正,向上为负)。这里,蛇默认向上移动。
设置食物
food = [-10, 0]
food列表定义了食物的初始位置,同样使用x和y坐标表示。这里食物的初始位置是(-10, 0)。
这些初始化步骤为游戏设置了基本的起点,包括蛇的初始位置和方向、食物的位置以及游戏窗口的标题。
☔3. 改变蛇移动的方向
# 改变蛇移动的方向
def change_direction(x, y):aim[0] = xaim[1] = y
- def 是 Python 中用来定义函数的关键字。
- change_direction 是函数名,这里表示改变方向的功能。
- x 和 y 是函数的参数,分别代表蛇在水平(x轴)和垂直(y轴)方向上的移动增量。
参数作用
- aim[0] = x:这行代码将水平方向的移动增量更新为参数 x 的值。如果 x 为正,蛇将向右移动;如果为负,则向左移动;如果为0,则蛇的水平位置不变。
- aim[1] = y:这行代码将垂直方向的移动增量更新为参数 y 的值。如果 y 为正,蛇将向下移动;如果为负,则向上移动;如果为0,则蛇的垂直位置不变。
注意事项
- 在实际的游戏实现中,需要确保蛇的移动方向不会违反游戏规则,例如蛇不能瞬间反向移动,这可能需要额外的逻辑来处理。
- 该函数直接修改了全局变量 aim,这意味着它对所有使用 aim 的代码都是可见的。在更复杂的程序中,可能需要考虑使用类和方法来封装数据和行为。
👊4. 绘制方块
def square(x, y, size, color):# 抬起画笔turtle.penup()# 画笔痕迹turtle.goto(x, y)# 放下画笔turtle.pendown()# 进行渲染turtle.color(color)turtle.begin_fill()# 在画布上画四笔转一圈生成一个方块for i in range(4):turtle.forward(size)turtle.left(90)turtle.end_fill()
turtle.penup() 这是让画笔抬起,这样当乌龟移动到绘制方块的起始位置时,不会在画布上留下痕迹。turtle.goto(x, y) 这是让乌龟移动到坐标 (x, y) 的位置,即方块左上角的起始位置。
turtle.pendown() 放下画笔,这样接下来的移动就会在画布上绘制线条。
turtle.color(color) 设置接下来绘制的图形的颜色。
turtle.begin_fill() 这行代码指示 turtle 开始填充封闭图形的内部。
turtle.end_fill() 结束填充过程,封闭图形的最后面,完成方块的绘制。
for i in range(4):turtle.forward(size)turtle.left(90)
循环执行四次,每次绘制方块的一边。turtle.forward(size) 让乌龟前进 size 个单位,turtle.left(90) 让乌龟左转90度,从而改变方向绘制下一条边。

这个函数可以被用来在 turtle 画布上绘制贪吃蛇游戏中的蛇的身体部分和食物。通过改变 size 和 color 参数,可以创建不同大小和颜色的方块。
🚀5. 检查蛇头是否在游戏区域内
def inside(head):return -250 < head[0] < 250 and -250 < head[1] < 250
函数体内的 return 语句包含了一个布尔表达式,用于检查 head 中的 x 和 y 坐标是否同时满足以下条件:
- head[0](即蛇头的 x 坐标)大于 -250 并且小于 250。
- head[1](即蛇头的 y 坐标)大于 -250 并且小于 250。
如果两个条件都为真,函数返回 True,表示蛇头在游戏窗口内;如果任一条件不满足(即蛇头坐标超出了这个范围),函数返回 False,表示蛇头已经撞到了游戏边界。
注意事项
在实际的游戏实现中,你需要根据实际的游戏窗口大小来调整函数中的边界值。上面的代码中使用的边界值 -250 和 250 是示例,具体值应根据你的游戏设计来设定。
🌈6. 定义蛇的移动函数
# 定义蛇的移动的函数
def sanke_move():head = copy.deepcopy(snake[-1])head = [head[0] + aim[0], head[1] + aim[1]]print(head[0], head[1])# 判断是否发生了碰撞if head in snake or not inside(head):print("Game Over!")square(head[0], head[1], 10, "red")return# 判断蛇碰到食物后的操作if head == food:food[0] = randrange(-15, 15) * 10food[1] = randrange(-15, 15) * 10else:snake.pop(0)snake.append(head)turtle.clear()square(food[0], food[1], 10, "blue")# 遍历蛇的列表画出蛇的长度for body in snake:square(body[0], body[1], 10, "black")# 更新,使动画的出现不是那么突兀turtle.update()turtle.ontimer(sanke_move, 300)
sanke_move 函数是贪吃蛇游戏中控制蛇移动的核心函数。
- 蛇头位置更新:通过将蛇的最后一个部分(尾部)的坐标与蛇的移动方向(aim)相加,计算出蛇头的新位置。
- 游戏结束判断:检查新计算出的蛇头位置是否超出了游戏边界(通过inside函数判断),或者蛇头是否与蛇身的其他部分重叠(即蛇撞到自己了)。如果是,则结束游戏,并在蛇头位置绘制一个红色方块表示碰撞点。
- 食物碰撞检测:如果蛇头位置与食物位置相同,表示蛇吃到食物。此时,生成新的食物位置,并让蛇增长(不移除蛇身的最前部分)。
- 蛇身更新:如果蛇没有吃到食物,移除蛇身的最前部分,模拟蛇的移动效果。然后将新计算的蛇头位置添加到蛇身列表的末尾。
- 绘制更新:清除画布,重新绘制食物和蛇身。食物用蓝色方块表示,蛇身用黑色方块表示。
- 动画效果:使用turtle.update()刷新屏幕显示,使上述绘制更新生效。
- 循环调用:通过turtle.ontimer设置定时器,每隔300毫秒自动调用一次sanke_move函数,从而实现蛇的连续移动,形成动画效果。
sanke_move函数负责根据用户的操作更新蛇的位置,检查游戏状态(如是否吃到食物或游戏是否结束),并更新屏幕上的显示,是贪吃蛇游戏的控制中心。
🎬7. 绑定键盘事件
设置屏幕大小
turtle.setup(500, 500)
这行代码设置了turtle画布的宽度和高度为500像素。这意味着蛇将在一个500x500像素的窗口内移动。
去除绘制动画
turtle.tracer(False)
turtle.tracer()函数控制是否在绘制图形时显示动画。将其设置为False可以关闭绘制方块时的动画效果,使方块几乎是立即出现的,这对于需要快速更新屏幕的游戏来说是必要的。
隐藏画笔(乌龟)
turtle.hideturtle()
这行代码隐藏了turtle模块中用于绘制的“乌龟”(即画笔)。在大多数游戏中,我们不需要看到这个画笔,只需要看到它绘制的图形。
监听键盘事件
turtle.listen()
turtle.listen()开始监听键盘事件,使得我们可以为特定的按键绑定特定的函数。
绑定键盘按键
turtle.onkey(lambda: change_direction(0, 10), "Up")
turtle.onkey(lambda: change_direction(0, -10), "Down")
turtle.onkey(lambda: change_direction(-10, 0), "Left")
turtle.onkey(lambda: change_direction(10, 0), "Right")
这四行代码将键盘的上下左右箭头键与change_direction函数绑定。当用户按下相应的箭头键时,会调用change_direction函数,并传入相应的参数,这些参数定义了蛇的新移动方向。
- “Up” 箭头:蛇向上移动(减少y坐标)。
- “Down” 箭头:蛇向下移动(增加y坐标)。
- “Left” 箭头:蛇向左移动(减少x坐标)。
- “Right” 箭头:蛇向右移动(增加x坐标)。
lambda函数是一个匿名函数,它创建了一个新的函数对象,这里用于简化onkey的回调函数。

⭐三、完整代码
import turtle
import copy
from random import randrange# 设置蛇的长度
snake = [[0, 0], [0, 10], [0, 20]]
# 蛇移动的方向(默认向上移动)
aim = [0, 10]
# 设置食物
food = [-10, 0]
wn = turtle.Screen()
# 设置标题
wn.title('贪吃蛇游戏')# 改变蛇移动的方向
def change_direction(x, y):aim[0] = xaim[1] = ydef square(x, y, size, color):# 抬起画笔turtle.penup()# 画笔痕迹turtle.goto(x, y)# 放下画笔turtle.pendown()# 进行渲染turtle.color(color)turtle.begin_fill()# 在画布上画四笔转一圈生成一个方块for i in range(4):turtle.forward(size)turtle.left(90)turtle.end_fill()def inside(head):return -250 < head[0] < 250 and -250 < head[1] < 250# 定义蛇的移动的函数
def sanke_move():head = copy.deepcopy(snake[-1])head = [head[0] + aim[0], head[1] + aim[1]]print(head[0], head[1])# 判断是否发生了碰撞if head in snake or not inside(head):print("Game Over!")square(head[0], head[1], 10, "red")return# 判断蛇碰到食物后的操作if head == food:food[0] = randrange(-15, 15) * 10food[1] = randrange(-15, 15) * 10else:snake.pop(0)snake.append(head)turtle.clear()square(food[0], food[1], 10, "blue")# 遍历蛇的列表画出蛇的长度for body in snake:square(body[0], body[1], 10, "black")# 更新,使动画的出现不是那么突兀turtle.update()turtle.ontimer(sanke_move, 300)# 设置屏幕的大小
turtle.setup(500, 500)
# 去除一个一个画方块的动画
turtle.tracer(False)
# 去掉箭头(画画用的画笔)
turtle.hideturtle()
# 用来监听键盘(获取键盘的事件)
turtle.listen()
# 用来监听函数(通过控制转向函数达到让蛇转向的目的)
turtle.onkey(lambda: change_direction(0, 10), "Up")
turtle.onkey(lambda: change_direction(0, -10), "Down")
turtle.onkey(lambda: change_direction(-10, 0), "Left")
turtle.onkey(lambda: change_direction(10, 0), "Right")
sanke_move()
# 不让屏幕立马消失
turtle.done()
相关文章:
【Python贪吃蛇】:编码技巧与游戏设计的完美结合
文章目录 🔥一、运行效果💥二、游戏教程✈1. 导入模块❤️2. 初始化游戏元素☔3. 改变蛇移动的方向👊4. 绘制方块🚀5. 检查蛇头是否在游戏区域内🌈6. 定义蛇的移动函数🎬7. 绑定键盘事件 ⭐三、完整代码 &a…...
2024.5.19 机器学习周报
引言 Abstract 文献阅读 1、题目 X-HRNET: TOWARDS LIGHTWEIGHT HUMAN POSE ESTIMATION WITH SPATIALLY UNIDIMENSIONAL SELF-ATTENTION 2、引言 高分辨率表示是人体姿态估计实现高性能所必需的,随之而来的问题是高计算复杂度。特别地,主要的姿态估…...
母亲节祝福html源码示例
创建一个完整的HTML页面,我可以为您提供一个简单的HTML模板,其中包含一些示例性的祝福语,并添加一些注释以帮助您理解如何扩展内容。 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8&qu…...
微信小程序开发中的权限管理与用户身份验证:守护数据安全与用户体验
微信小程序开发中的权限管理与用户身份验证:守护数据安全与用户体验 引言 在微信小程序开发中,权限管理和用户身份验证是确保数据安全、保护用户隐私以及提供个性化服务的关键环节。本文将深入探讨微信小程序中如何实现权限管理和用户身份验证…...
Python3 笔记:二进制的转换
十进制是逢十进一,二进制就是逢二进一。 十进制里最大的数字是9,二进制里最大的数字是1。 11010010001000010000010000001000000010^0110^11010^210010^3100010^41000010^510000010^6100000010^7100000002^012^122^242^382^4162^5322^6642^7128 1、十进…...
代码审计-PHP模型开发篇动态调试反序列化变量覆盖TP框架原生POP链
知识点 1、PHP审计-动态调试-变量覆盖 2、PHP审计-动态调试-原生反序列化 3、PHP审计-动态调试-框架反序列化PHP常见漏洞关键字 SQL注入: select insert update delete mysql_query mysqli等 文件上传: $_FILES,type"file"&…...
前端动态旋转地球背景
效果图 贴下源码 <template><div class"map-bg"><div class"canvas" id"canvs"></div><canvas class"canvasxk" id"canv"></canvas></div> </template><script setup …...
MySQL中的子查询
子查询,在一个查询语句中又出现了查询语句 子查询可以出现在from和where后面 from 表子查询(结果一般为多行多列)把查询结果继续当一张表对待 where 标量子查询(结果集只有一行一列)查询身高最高的学生,查询到一个最高身高 列子查询(结果集只有一行多列) 对上表进行如下操作 …...
Unity打开安卓设备不同的设置面板
1,打开安卓设备不同的设置面板,我还贴心的把Android官网的链接放下面了 2,使用也很方便:unity按钮事件上拖这个脚本,注册MyOpenAndroidSettings方法,参数 填 和枚举值相应的数字 // 功能:打开…...
低空经济+无人机:低空物资运输技术详解
随着科技的飞速发展和航空产业的日益壮大,低空经济已成为全球经济的重要组成部分。无人机作为低空经济的重要载体,其在低空物资运输领域的应用逐渐凸显,为物流、救援等多个领域带来了革命性的变革。 一、低空经济概述 低空经济是指在垂直高度…...
全场景智能终端RK3288主板在智能垃圾回收项目的应用,支持鸿蒙,支持全国产化
全场景智能终端主板AIoT-3588A推出的智能化垃圾回收项目,旨在解决城市化进程中日益突出的垃圾处理问题。智能垃圾分类箱具备触屏操作、自动称重、分类投放以及电子语音播报提示等多项功能,居民能够经过分类积分卡、手机扫码、人脸识别等多种途径进行投放…...
QT设计模式:建造者模式
基本概念 建造者模式是一种创建型设计模式,它允许你创建复杂对象的过程独立于该对象的组成部分以及它们的组装方式。这样可以构造出不同的对象表示。 在建造者模式中,将创建对象的过程和对象的表示分离,通过一步步的构建,可以得…...
个人微信api
简要描述: 退出群聊 请求URL: http://域名地址/quitChatRoom 请求方式: POST 请求头Headers: Content-Type:application/json Authorization:login接口返回 参数: 参数名 必选 类型 …...
使用Ownips工具获取海外电商网站wish商品价格
一、引言 在数字化浪潮汹涌的今天,互联网已经成为我们生活、工作中不可或缺的一部分。而在这个虚拟的世界里,每一个设备都需要一个独特的标识来确保信息的准确传递,这个标识就是IP地址。而在众多IP地址中,静态IP因其独特的稳定性…...
【FFmpeg】调用ffmpeg进行H264软解
调用FFmpeg库实现264软件解码 1. FFmpeg的编译2. 调用FFmpeg实现H264软解2.1 基本框架2.2 代码实现2.3 测试结果 3. 分析工具3.1 码流分析3.2 YUV分析 示例工程 【FFmpeg】调用FFmpeg库实现264软编 1. FFmpeg的编译 FFmpeg在Windows下的编译参考:http://t.csdni…...
网络安全防护:抵御DDoS和CC攻击
在当今数字化时代,网络安全已成为任何组织或个人不可忽视的重要议题。DDoS(分布式拒绝服务)攻击和CC(命令与控制)攻击作为两种最为常见的网络攻击方式,给网络运营者和用户带来了巨大的威胁和影响。本文将介…...
初次查询大数据信用报告,需要注意哪些问题?
随着大数据的普及,基于大数据技术的大数据信用也变得越来越重要,比如在申贷之前,不少地方都会查询申贷人的大数据信用,作为风险控制的必要手段,那对于初次查询大数据信用报告的人来说,需要注意哪些问题呢?…...
最短路径[floyd算法]-----视频讲解+代码实现
求最短路径,一般有三种方法: 单源最短路径--Dijkstra算法 此算法只能求不带负权值的有向无环图 单源最短路径--Bellman-Ford算法(少考) 此算法优点在于:可以求带权值的右向无环图 但只是缺点明显,时间复杂度…...
图像/视频恢复和增强CodeFormer
github:https://github.com/sczhou/CodeFormer 尝试增强旧照片/修复人工智能艺术 面部修复 面部色彩增强和恢复 脸部修复...
WPF中ObservableCollection
在WPF(Windows Presentation Foundation)中,ObservableCollection<T> 是一个非常重要的类,它用于实现动态数据绑定功能。这个类位于 System.Collections.ObjectModel 命名空间中,是 ICollection<T>, IList…...
Docker vs Pip:MinerU本地部署全攻略,哪种方式更适合你的PDF解析需求?
Docker与Pip部署MinerU深度对比:如何为PDF解析选择最佳方案 在文档自动化处理领域,PDF解析工具的选择往往直接影响工作效率。MinerU作为一款开源的PDF解析工具,因其对复杂排版的良好支持而受到开发者青睐。但面对Pip和Docker两种主流部署方式…...
别再写重复代码了!用WPF Behavior封装一个可复用的鼠标拖拽缩放控件(附完整源码)
用WPF Behavior打造高复用鼠标拖拽缩放控件:从原理到实战封装 在WPF企业级应用开发中,交互控件的重复开发是效率杀手。想象一下:当产品经理要求为项目中的图表、图片预览器和自定义控件都添加相似的拖拽缩放功能时,你是选择在每个…...
推荐系统优化秘籍:如何用Metric Learning解决冷启动问题?
推荐系统优化秘籍:如何用Metric Learning解决冷启动问题? 在推荐系统领域,冷启动问题一直是困扰算法工程师和产品经理的核心挑战之一。新用户缺乏历史行为数据,新商品没有足够的曝光记录,传统协同过滤方法在这些场景下…...
基于MATLAB的图像加密解密系统 可以正确无误的对图像进行加密和解密 带GUI界面
基于MATLAB的图像加密解密系统 可以正确无误的对图像进行加密和解密 带GUI界面,一步一步完整运行你是否有过这样的疑问——如何让一张普通图片变成外星密文?在MATLAB里玩转图像加密真的可以像搭积木一样简单。今天咱们就来捣鼓一个带界面的图像加密系统&…...
C++传记 类的定义(面向对象)
面向对象编程(OOP)是C的核心特性之一,其核心思想是“封装、继承、多态”,而则是实现面向对象编程的基础载体——它本质上是一种自定义的数据类型,用于封装一组相关的属性(数据)和行为࿰…...
[PTA]从汉诺塔到斐波那契:递归思想在经典算法问题中的实战解析
1. 递归思想:从神话到代码的魔法之旅 第一次接触递归时,我盯着汉诺塔的代码看了整整三小时。那种感觉就像小时候听魔术师说"见证奇迹的时刻"——明明看着他把鸽子变没了,却死活想不通机关在哪。递归就是编程世界最优雅的魔术&#…...
OpenClaw超轻量方案:nanobot镜像对接QQ机器人全流程
OpenClaw超轻量方案:nanobot镜像对接QQ机器人全流程 1. 为什么选择nanobot镜像 去年夏天,我在尝试将OpenClaw接入QQ机器人时遇到了不少麻烦。当时需要分别部署模型服务、配置OpenClaw网关、调试QQ机器人接口,整个过程耗费了整整三天时间。直…...
告别硬件!用Proteus8.9和VSPD虚拟串口,5分钟搞定51单片机串口通信仿真
零成本玩转51单片机串口通信:Proteus与VSPD虚拟串口实战指南 记得刚接触单片机开发时,最头疼的就是硬件问题——买开发板要钱,买USB转串口模块要钱,连杜邦线都得精打细算。直到发现ProteusVSPD这对黄金组合,才明白原来…...
(ubuntu黑屏)Z890M + U7 265KF + RTX 5070 Ti 安装 Ubuntu 22.04.5 实战记录(网卡 + 显卡驱动全解)
本文记录了在技嘉 Z890M Intel Core Ultra 7 265KF RTX 5070 Ti 新平台上,成功安装 Ubuntu 22.04.5 并解决网卡、显卡驱动问题的完整过程,适合同类配置参考。一、硬件环境组件型号主板技嘉 Z890M 小雕(带 WiFi)CPUIntel Core Ul…...
计算机毕设 java 基于 Java+Spring 的疫苗接种管理系统的设计与实现 智能疫苗接种预约系统 疫苗接种全流程管理平台
计算机毕设 java 基于 JavaSpring 的疫苗接种管理系统的设计与实现 69geq9(配套有源码 程序 mysql 数据库 论文)本套源码可以先看具体功能演示视频领取,文末有联 xi 可分享在社会对公共卫生安全愈发重视的背景下,疫苗接种作为重要…...
