当前位置: 首页 > news >正文

20244218骆云灵澜 Python实验四

20254106 2025-2026-6 《Python程序设计》实验4报告
课程:《Python程序设计》
班级: 2442
姓名: 骆云灵澜
学号:20244218
实验教师:王志强
实验日期:2026年6月12日
必修/选修: 专选课

一、实验内容
Python综合应用:爬虫、数据处理、可视化、机器学习、神经网络、游戏、网络安全等。
例如:编写从社交网络爬取数据,实现可视化舆情监控或者情感分析。
例如:利用公开数据集,开展图像分类、恶意软件检测等
例如:利用Python库,基于OCR技术实现自动化提取图片中数据,并填入excel中。
例如:爬取天气数据,实现自动化微信提醒
例如:利用爬虫,实现自动化下载网站视频、文件等。
例如:编写小游戏:坦克大战、贪吃蛇、扫雷等等
注:在Windows/Linux系统上使用VIM、PDB、IDLE、Pycharm等工具编程实现。
评分标准:
(1)程序能运行,功能丰富(至少5个功能)。(需求提交源代码,并建议录制程序运行的视频)15分
(2)综合实践报告,要体现实验分析、设计、实现过程、结果等信息,格式规范,逻辑清晰,结构合理。20分。
(3)在实践报告中,需要对全课进行总结,并写课程感想体会、意见和建议等。10分
二、实验过程
1.程序选择
在确定综合实践题目时,我其实有过纠结。最开始想过做数据分析或者爬虫项目,但看着一堆数据和网页结构,总觉得自己还没修炼到那个境界。还是选择了对我来讲更有兴趣也更好理解的小游戏开发。最后选择贪吃蛇,主要是因为它算得上很多人的童年回忆,看起来规则简单,但真正动手编写时才发现并没有想象中那么容易。项目中需要处理键盘控制、碰撞检测、随机生成食物等问题,能够把课堂上学到的知识串联起来。再加上自己本来就对小游戏更感兴趣,于是决定自己尝试完成一个能真正运行起来的贪吃蛇游戏。
2.玩法设计
本次用 Python 的 turtle 库写了贪吃蛇小游戏,界面做了比较花里胡哨的美化,背景深色搭配彩色边框。蛇每吃到食物就会变长,身体每段颜色都不一样,食物也会随机换颜色。游戏会记录当前得分和历史最高分,吃得越多速度越快,撞到墙或者自己身体就会结束游戏。程序加了空格控制,打开先按空格开始,输了之后再按空格就能重新玩,靠循环刷新画面、键盘按键来操控蛇移动。
3.代码编写
源代码展示:

点击查看代码
import turtle
import random
import time# ===================== 窗口美化配置 =====================
window = turtle.Screen()
window.title("贪吃蛇")  # 修改标题
window.bgcolor("#050520")
window.setup(width=650, height=650)
window.tracer(0)# 霓虹装饰边框
border_draw = turtle.Turtle()
border_draw.hideturtle()
border_draw.speed(0)
border_draw.pensize(4)
border_draw.color("#00ffff")
border_draw.penup()
border_draw.goto(-310, -310)
border_draw.pendown()
for _ in range(4):border_draw.forward(620)border_draw.left(90)
border_draw.penup()# ===================== 蛇头 =====================
head = turtle.Turtle()
head.speed(0)
head.shape("square")
head.color("#39ff14")
head.shapesize(stretch_wid=1.1, stretch_len=1.1)
head.penup()
head.goto(0, 0)
head.direction = "right"# ===================== 食物 =====================
food = turtle.Turtle()
food.speed(0)
food.shape("circle")
food.shapesize(stretch_wid=0.9, stretch_len=0.9)
food.penup()
food.goto(100, 0)
food_color_list = ["#ff005c", "#fffb00", "#00fff7", "#ff7700", "#ff00ff"]
food.color(random.choice(food_color_list))segments = []
# 超多霓虹配色,每吃一节换一个颜色
color_pool = ["#ff3333", "#ff9900", "#ffff00", "#33ff33","#00ffcc", "#00ccff", "#3366ff", "#9933ff","#ff33cc", "#ff6699", "#66ff66", "#00ffff"
]# ===================== 分数文字面板 =====================
score = 0
high_score = 0
game_running = False  # 游戏运行状态标记score_pen = turtle.Turtle()
score_pen.speed(0)
score_pen.color("#ffffff")
score_pen.penup()
score_pen.hideturtle()
score_pen.goto(0, 290)# 提示文字画笔
tip_pen = turtle.Turtle()
tip_pen.hideturtle()
tip_pen.color("#00ffff")
tip_pen.penup()
tip_pen.goto(0, 0)# 更新分数
def update_score():score_pen.clear()score_pen.write(f"当前得分:{score}    最高分:{high_score}", align="center", font=("Microsoft YaHei", 22, "bold"))# 显示开始提示
def show_start_tip():tip_pen.clear()tip_pen.write("贪吃蛇\n\n按空格键开始游戏", align="center", font=("Microsoft YaHei", 32, "bold"))# 显示死亡重开提示
def show_restart_tip():tip_pen.clear()tip_pen.write("游戏结束!\n按空格键重新开始", align="center", font=("Microsoft YaHei", 32, "bold"))# 空格开始/重新开始游戏
def start_game():global game_running, score, high_score, delayif not game_running:# 重置所有数据head.goto(0, 0)head.direction = "right"for seg in segments:seg.goto(1000, 1000)segments.clear()score = 0delay = 0.12update_score()tip_pen.clear()game_running = True# ===================== 功能函数 =====================
def go_up():if head.direction != "down":head.direction = "up"def go_down():if head.direction != "up":head.direction = "down"def go_left():if head.direction != "right":head.direction = "left"def go_right():if head.direction != "left":head.direction = "right"def move():if head.direction == "up":y = head.ycor()head.sety(y + 20)elif head.direction == "down":y = head.ycor()head.sety(y - 20)elif head.direction == "left":x = head.xcor()head.setx(x - 20)elif head.direction == "right":x = head.xcor()head.setx(x + 20)# 撞墙闪烁
def wall_flash():for _ in range(4):window.bgcolor("#ff2222")window.update()time.sleep(0.08)window.bgcolor("#050520")window.update()time.sleep(0.08)# 死亡文字特效
def death_effect():death_text = turtle.Turtle()death_text.hideturtle()death_text.color("#ff2255")death_text.penup()death_text.goto(0, 0)death_text.write("游戏结束!", align="center", font=("Microsoft YaHei", 36, "bold"))window.update()time.sleep(1)death_text.clear()# 键盘绑定
window.listen()
window.onkeypress(go_up, "Up")
window.onkeypress(go_down, "Down")
window.onkeypress(go_left, "Left")
window.onkeypress(go_right, "Right")
window.onkeypress(start_game, "space")  # 绑定空格键# ===================== 主游戏循环 =====================
def game_loop():global score, high_score, game_running, delaydelay = 0.12show_start_tip()update_score()while True:window.update()# 游戏未运行,不执行逻辑if not game_running:time.sleep(0.05)continue# 撞墙判定if head.xcor() > 290 or head.xcor() < -290 or head.ycor() > 290 or head.ycor() < -290:wall_flash()death_effect()game_running = Falseshow_restart_tip()time.sleep(0.5)continue# 吃到食物if head.distance(food) < 20:x = random.randrange(-280, 280, 20)y = random.randrange(-280, 280, 20)food.goto(x, y)food.color(random.choice(food_color_list))# 新增一节身体,根据当前长度取对应颜色,每吃一个换色new_seg = turtle.Turtle()new_seg.speed(0)new_seg.shape("square")new_seg.shapesize(1.05)# 按身体长度索引取颜色,无限循环彩色池color_index = len(segments) % len(color_pool)new_seg.color(color_pool[color_index])new_seg.penup()segments.append(new_seg)score += 10if score > high_score:high_score = scoreupdate_score()if delay > 0.04:delay -= 0.003# 蛇身跟随total_seg = len(segments)for index in range(total_seg - 1, 0, -1):prev_x = segments[index - 1].xcor()prev_y = segments[index - 1].ycor()segments[index].goto(prev_x, prev_y)if total_seg > 0:head_x = head.xcor()head_y = head.ycor()segments[0].goto(head_x, head_y)move()# 撞到自身for seg in segments:if seg.distance(head) < 10:wall_flash()death_effect()game_running = Falseshow_restart_tip()time.sleep(0.5)breaktime.sleep(delay)# 启动
print("贪吃蛇启动!按空格键开始游戏,死亡后按空格重新开始")
game_loop()
window.mainloop()
(我尝试过下载pygame来做代码,但最后因为出现各种无法正常运行,按键无法使用的情况,所以我就用了python自带的turtle库)tkinter 是 Python 自带的标准图形界面库,无需额外安装。它提供窗口、画布、按钮等组件,可用于开发桌面小游戏和工具软件,简单易学。 (1)导入模块和配置参数

image
turtle:核心图形库,用来绘制蛇、食物、边框、文字等。
random:随机生成食物位置和颜色。
time:控制游戏帧率和死亡特效中的延时。
窗口设置部分:

image
tracer(0) 是一个关键设置:关闭turtle的自动画面刷新,然后在主循环中手动调用 window.update(),这样可以让动画更流畅,也方便控制帧率。
(2)彩虹装饰边框

image
这段代码画了一个青色发光的边框,让游戏窗口看起来像霓虹灯牌。penup() 和 goto() 移动画笔到起始点,pendown() 开始画,循环四次画出一个正方形边框。最后 penup() 抬起画笔,避免干扰后续绘图。
(3)蛇头与食物

image
蛇头是一个绿色的正方形方块,稍微放大了一点(stretch_wid=1.1),看起来更醒目。direction 属性记录了当前移动方向,用于 move() 函数。
食物:

image
食物是圆形,尺寸略小,颜色从五色列表中随机选取。每次吃到食物后,新食物会再次随机变色,增加视觉乐趣。
(4)蛇身管理

image
蛇身每节也是一个 turtle.Turtle 对象,形状也是正方形。每吃到食物,就新建一节,并根据当前身体长度从 color_pool 中循环取色,这样蛇身会呈现七彩渐变效果,非常炫酷。
身体跟随的逻辑在主循环中:

image
这是经典的“尾随”算法:从最后一节开始,每一节移动到前一节的位置,然后第一节移动到蛇头原来的位置。注意遍历要倒序,否则会覆盖位置导致错误。
(5)分数与提示文字面板

image
两个独立的 Turtle 对象用来显示文字,互不干扰。score_pen 固定在屏幕顶部中间显示“当前得分”和“最高分”;tip_pen 在屏幕中央显示开始提示或结束提示。
(6)移动控制与防反向

image
这里做了简单防反向:如果当前方向是“下”,就不能直接改为“上”,防止蛇瞬间掉头自杀。但是代码中没有用缓冲方向,因为 turtle 的事件响应和主循环是顺序执行的,不会出现一帧内多次方向改变的问题,所以这样写已经足够。
移动函数 move() 根据 head.direction 改变蛇头的 x 或 y 坐标(每次移动 20 像素,因为每个格子边长 20)。
(7)死亡特效与碰撞检测
撞墙检测:

image
wall_flash() 让背景快速闪烁红色四次:

image
death_effect() 用一个新的 Turtle 对象在中央显示“游戏结束!”大文字,停留一秒后清除。
自身碰撞:

image
遍历所有身体节,如果蛇头距离某节身体小于10像素(因为格子边长20,蛇头与身体中心距离小于10表示重叠),则游戏结束。
食物碰撞:

image
这里需要注意的是:生成新食物位置时,没有检查是否与蛇身重叠。因为游戏区域比较大(28×28个格子),蛇身长度一般不会占满,偶尔重叠的概率很低,而且玩家如果正好碰到那种情况,相当于白吃一个食物(无额外惩罚),我觉得可以接受。当然,严格的做法应该写一个循环检测直到生成空位。
(8)游戏主循环与开始/重启机制

image
空格键绑定 start_game,只有游戏未运行时(game_running == False)才执行重置逻辑。重置时将身体节全部移到屏幕外((1000,1000)),并清空列表,蛇头复位,分数和速度恢复初始。
主循环:

image
while True 是无限循环,通过 game_running 开关来控制是否执行游戏逻辑。time.sleep(delay) 控制蛇的移动速度,delay 越小越快。

需要注意:window.update() 必须在每一帧都调用,否则画面不会刷新。time.sleep() 会阻塞,但只阻塞当前线程,不影响事件监听(因为turtle的键盘事件是在主循环中轮询的,阻塞期间也能响应按键,但方向改变可能略有延迟,不过总体可接受)。
4. 运行视频
由于代码完全运行在本地,我录制了一段视频上传到小破站展示游戏效果。视频内容包括:启动界面、按空格开始、吃食物蛇身变长变色、速度逐渐加快、故意撞墙触发闪烁特效、游戏结束提示、按空格重新开始。视频链接如下:

https://www.bilibili.com/video/BV1pMjN6cETf/?spm_id_from=333.1387.homepage.video_card.click&vd_source=d052ae5f9805081de689e58c6db7ef1b

四、实验过程中遇到的问题和解决过程
问题1:身体跟随逻辑写反了,蛇身乱跑
描述:一开始写身体跟随的时候,我用了正序循环:

for i in range(len(segments)-1):
segments[i+1].goto(segments[i].xcor(), segments[i].ycor())

结果蛇身会像毛毛虫一样扭曲,因为后面的节先移动到前面节的位置,然后前面节再移动时覆盖了后面的。正确做法应该是倒序,从最后一节开始往前移动。
解决方法:改成:

for i in range(len(segments)-1, 0, -1):
segments[i].goto(segments[i-1].xcor(), segments[i-1].ycor())

这样就实现了尾部跟随头部路径的效果。

问题2:撞墙后背景闪烁不自然
描述:一开始撞墙时我直接修改 window.bgcolor 并 time.sleep,发现闪烁过程中无法响应任何操作,而且闪烁频率太快,效果不好。
解决方法:用循环控制闪烁次数,每次闪烁时更新画面 window.update(),并给予短暂的 time.sleep(0.08),让人眼能明显感知到红色闪烁。同时闪烁结束后才显示死亡文字,顺序合理。

问题3:开始提示和死亡提示文字重叠
描述:游戏结束后,tip_pen 上显示了“游戏结束!按空格重新开始”,但开始时的提示没有被清除,导致文字重叠。
解决方法:在 start_game() 和显示死亡提示前,都调用 tip_pen.clear() 清空之前的文字。另外,show_start_tip() 只在最开始调用一次,游戏结束后调用 show_restart_tip() 覆盖原有文字,逻辑就清晰了。

问题4:食物生成在蛇身上
描述:极少数情况下,随机生成的食物坐标会与蛇身重叠,导致蛇移动到那个格子时吃不到(碰撞检测可能触发也可能不触发)。绷不住了。
解决方法:理论上应该在生成食物时循环检测直到找到空位。但考虑到游戏区域有 28×28个格子,蛇身最多占满也就几百,概率不高,而且偶尔出现也不会导致游戏崩溃。为了代码简洁,我没有加入这个检测。参考ai的意见,如果后续改进,会写一个 get_free_position() 函数。

五、实验总结
这次贪吃蛇游戏算是这学期Python课程里我写得最完整的一个程序了。虽然之前课上跟着老师也写过一些小程序,但这次从零开始自己设计整个游戏逻辑,感觉难度还是上了一个台阶。
一开始我其实想用pygame,但实际操作不太顺利,就转用了turtle。turtle是Python自带的,不需要额外装东西,比较方便。不过真正做游戏才发现,turtle用来做简单的动画还好,要实现实时键盘控制、碰撞检测和身体跟随,还是需要仔细设计循环结构和状态变量。整个代码写下来,花时间最多的部分是蛇身的移动逻辑。最开始我正着遍历身体位置,结果蛇走起来身体会扭曲,后来查了一些资料,明白需要从尾部往头部方向更新坐标,这样才能保证每一节都正确移动到前一节的位置。这个问题的解决让我对列表的索引和循环顺序有了更深的理解。
另一个难绷的问题是边界碰撞的数值调整。窗口大小和蛇头移动步长之间需要匹配,我一开始边界判断写错了,导致蛇明明还在屏幕内却被判定死亡。后来画了坐标草稿,一步一步推算出合理的边界阈值才解决。这种细心调试的过程,虽然枯燥,但真的能锻炼逻辑思维。我也加了一些自己的设计,比如七彩蛇身、霓虹边框、死亡闪烁特效。这些不是必须的功能,但加上之后游戏看起来更完整了,自己做着也有成就感。最高分记录我是在程序运行期间用变量保存的,没有做文件持久化,因为觉得turtle做文件操作稍微麻烦了点,这部分如果以后改进可以加上。
通过这次实验,我最大的收获是学会了怎么把一个稍大的任务拆分成小模块去实现。先让蛇能动,再加上食物,再处理得分和身体增长,最后加特效和边界判断——一步步来,虽然中间会出很多bug,但每个bug修好之后,离最终目标就更近一步。
最后,感谢王老师这学期的教学。我原本对编程挺畏惧的,现在虽然不敢说很熟练,但至少遇到问题不会慌了。以后如果有时间,我想把这个游戏用pygame重新写一遍,加个音效和菜单界面,应该会更有意思。

六、其他(感悟、思考等)
(一)课程总结和心得体会
作为一名文科生,选修Python课程之前,我一直觉得编程是理工科专属技能,而代码则像某种神秘咒语看得见却看不懂。本学期的学习经历成功打破了我的这种刻板印象。从石头剪刀布、猜数字等小游戏,再到后来的文件操作和爬虫应用,还可以运用函数定义、循环语句等编写简单的应用程序。这些内容既丰富了我的知识储备,提升了我的理科素养,也让我感受到了“码农”的乐趣,使我改变了对敲代码索然无味的刻板印象。
其次,我培养了一丝不苟、细致入微的学习习惯,也锻炼了思维方式,提高了理解能力。在Python代码的编写中有很多时刻需要注意的地方,比如说标点符号全部要用英文半角符号,要注意浮点型数据在计算中向其他类型数据的转换、要注意正确的缩进,不能使用Python中的保留字符,英文字母一定要拼写正确且前后变量书写要一致,“=”和“==”的区别要牢记。在代码运行中,往往“差之毫厘谬以千里”,一个个提示的错误总会提醒我细致细致再细致。在学习初期,我对变量的把握一直不是很清晰,比如会疑惑为何前一行定义x=10,后一行又可以定义x=“hello”,后来在请教同学之后,我明白Python作为动态类型语言,变量可以通过重新赋值成为不同类型的数据。类似这样的例子使我对编程语言有了更为深入的理解,也使我有效建立起来了编程逻辑和代码思维。
在这个基础上,我的工作学习效率也得到了提升。比如在学习中,我可以通过爬虫在百度等浏览器或网站上高效查找相关资料。在今后的学习生活中,我坚信一定会有更多的Python知识与实际需求双向奔赴,让编程和代码真正改变我的大学生活。
(二)课程建议
1.本课程确实难度较大,对于行管专业文科的同学来讲更是有着极大的挑战。在课上的确难以理解相关知识点,经常跟不上老师的介绍节奏。建议老师在每周上课前五到六天提前发布预习内容并鼓励同学们先自主学习,对知识框架有一个大致的了解,这样可能有助于改善同学们听不懂的状况。
2.本学期的英语打卡环节让我受益匪浅,不仅积累了编程相关的专业词汇,更为备考六级打下基础,希望能延续这一学习方式。
Python课程的结束不是终点,而是探索编程世界的新起点。这份学习经历赋予我的思维方法、解决问题的勇气,以及对编程的兴趣,都将持续影响我的学习与生活。最后感谢老师一学期的辛苦付出,每天都笑嘻嘻地给我们讲课答疑,上课也很有活人气息,让人心情很愉快。:)

http://www.jsqmd.com/news/1019781/

相关文章:

  • 小米电视ADB卸载保姆级教程:对照这张表,再也不怕删错系统应用
  • 保姆级教程:手把手教你下载并安装MATLAB R2023b(附详细步骤与常见问题解决)
  • 2026年6月超声波泥位计品牌好评榜:国产头部阵营技术突围与市场实证 - 水质仪表品牌排行榜
  • GitLab CE 15.11在麒麟V10的安装与调优:不止是安装,还有防火墙、端口和日常运维命令
  • 2026年6月邳州黄金回收市场深度调查:三家诚信商家排名与避坑指南 - 钦扬网络
  • NXP eFlexPWM寄存器深度解析:从架构到三相电机驱动实战
  • 从一次现场调试讲起:SL651-2014协议中那些容易踩的坑(功能码、CRC与数据标识符详解)
  • 告别繁琐!用Wix Toolset v3.11为你的WPF项目制作专业安装包(附中文界面配置)
  • FlexCAN寄存器深度解析:从位定时计算到中断机制实战
  • 如何快速上手Bilibili-Evolved:新手必看的哔哩哔哩增强脚本完整指南
  • 盐城专业改灯门店汇总(盐都区汽配城集中,连锁 + 本地老店) - Ayu8888
  • 神经回放机制:让AI具备情境触发的经验重演能力
  • 东莞GEO优化公司哪家好?2026年避坑指南:别再为“无效曝光”买单 - GEO优化
  • Win11系统下,用笔记本自带蓝牙连接HC05模块的正确姿势(解决搜不到设备问题)
  • Typora 1.4.8 vs 新版:老版本还香吗?功能对比与降级安装全指南
  • 深度解析Windows内核级硬件伪装技术的5大实战应用场景
  • 嵌入式TDM接口原理与MSC711x实战配置指南
  • 告别龟速下载!PyCharm 2023.2.5+ 保姆级镜像源配置(清华/阿里云/中科大)
  • 内行私藏!上海5家猫犬舍深度测评,真正能养得住的健康宠,只认准这一家 - 萌宠俱乐部
  • 【小白也能轻松用】本地AI智能体搭建,OpenClaw零基础简易部署方法(含最新安装包)
  • 2026年6月电磁流量计品牌好评榜:国产头部阵营技术突围与市场格局深度解析 - 水质仪表品牌排行榜
  • StreamFX插件实战指南:5个高效方法打造专业级OBS直播画面
  • 不只是配置:在Ubuntu 20.04上用VSCode搭建OpenGL学习与调试环境
  • MATLAB R2023b Windows版安装后必做的几件事:从环境配置到第一个脚本运行
  • MDPI投稿被秒拒?别慌!手把手教你用Turnitin自查重复率,从21%降到录用标准
  • MyComputerManager:Windows系统“此电脑“界面终极清理与高效自定义工具
  • 盐城车视觉改灯|汽配城门店,打造极致专业感全套方案 - Ayu8888
  • NXP EdgeLock Enclave HSM错误码解析与嵌入式安全调试实践
  • Qt4.8安装避坑全记录:从下载、配置到跑通第一个Demo(附资源与常见错误解决)
  • 手把手排查:Oracle数据库LMHB/VKTM进程提权失败(ORA-00800)的完整诊断流程