【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…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
