20244127 2024-2025-2《Python程序设计》实验四报告
20244127 2024-2025-2 《Python程序设计》实验四报告
课程:《Python程序设计》
班级: 2441
姓名: 王晓凤
学号:20244127
实验教师:王志强
实验日期:2025年5月13日
必修/选修: 公选课
1.实验内容
Python综合应用:爬虫、数据处理、可视化、机器学习、神经网络、游戏、网络安全等。
例如:编写从社交网络爬取数据,实现可视化舆情监控或者情感分析。
例如:利用公开数据集,开展图像分类、恶意软件检测等
例如:利用Python库,基于OCR技术实现自动化提取图片中数据,并填入excel中。
例如:爬取天气数据,实现自动化微信提醒
例如:利用爬虫,实现自动化下载网站视频、文件等。
例如:编写小游戏:坦克大战、贪吃蛇、扫雷等等
注:在Windows/Linux系统上使用VIM、PDB、IDLE、Pycharm等工具编程实现。
2.实验过程及结果
一、了解贪吃蛇小游戏的游戏规则,构思程序大致设计的逻辑框架
贪吃蛇小游戏的逻辑概述:
游戏角色会在屏幕上爬动。玩家可以通过按下方向键来控制小蛇的移动方向,从而使小蛇吃到食物。如果方向操作有误,使得小蛇撞上墙壁或者首尾相连,则游戏结束。
二、根据游戏规则和框架编写程序,不断改进优化
(1)配置好实验环境
在实验正式开始前,先确保Pycharm和Pygame的开发环境均已配备完毕,做好充足准备工作。
(2)导入库和创建游戏窗口
需要的库:
tkinter:用来做游戏界面
random:用来随机生成食物位置
使用 Tkinter 的Canvas创建游戏区域,尺寸为 600×400 像素,每个元素以 20×20 像素的块为单位。
蛇初始由 3 个黑色方块组成,坐标分别为(100,100)、(80,100)、(60,100),形成水平向右的蛇身。
direction记录当前移动方向,next_direction避免反向移动(如向上时不能直接向下)。
game_over标志控制游戏循环是否结束。

(3)食物生成
通过random.randint计算食物坐标,确保其位于窗口内且不与蛇身重叠。
(width - block_size) // block_size确保食物右侧不超出窗口边界。
使用while True确保生成的食物位置合法,避免蛇初始状态与食物重叠。

(4)蛇移动与碰撞检测
移动机制:
①蛇头按当前方向移动一个块单位,蛇身通过insert(0)和pop()实现 “头部延伸、尾部收缩” 的效果。
②若吃到食物,保留蛇尾(蛇身增长一节),否则移除蛇尾。
碰撞检测:
①撞墙:判断蛇头是否超出窗口边界。
②自噬:检查新蛇头是否在蛇身坐标列表中,避免蛇咬到自己。

(5)方向控制
通过keysym获取按键名称,仅允许与当前方向非相反的按键生效(如当前向右时,禁止向左按键)。
使用next_direction暂存按键方向,避免同一帧内多次按键导致方向混乱。

(6)游戏循环与更新
通过after方法实现定时刷新(150ms / 次),形成动画效果。每次循环更新方向、移动蛇、重绘界面,直至game_over为True。
固定延迟导致游戏速度不变,可优化为根据分数动态调整速度(如分数越高,延迟越短)。

(7)元素绘制
每次循环清空画布后重新绘制所有元素,简单直观。
蛇身用矩形表示,食物用圆形表示,通过颜色区分(黑蛇、红食物)。

3.实验过程中遇到的问题和解决过程
问题1:代码未反应出较大错误,但是无法运行;
问题1解决方案:上网查阅资料后发现,需要先在pycharm内安装pygame,根据网络上分享的教程并在同学的帮助下,将代码进行修改,使得游戏界面可正常进行显示并可进行操作。
问题2:一开始小蛇行进速度太快,影响玩家体验;
问题2解决方案:通过上网查找资料,修改行进速度并不断进行测试,使得游戏体验更加舒适。
- 感悟思考
初次翻开 Python 教材时,密密麻麻的代码符号让我这个文科生直犯怵,“for”“while”“if” 这些英文单词排列组合成的陌生句式,仿佛构筑起一道难以跨越的高墙。可当我真正走进这门公选课,才发现编程世界并非冰冷生硬,而是充满了趣味与惊喜。课堂上,老师化身,用一个个鲜活的案例将抽象知识具象化。记得“类”时,老师以图书馆类比,把不同的书比作元素,瞬间就让原本晦涩的概念变得清晰易懂。在掌握基础语法后,我们开始尝试用代码解决实际问题。从编写简单的“hello,world”语句,到运行石头剪刀布等小游戏程序,每一次成功运行代码,都像是解开一道复杂谜题,成就感如潮水般涌来。尤其是每次点下运行键,程序成功运行的那一刻,看着黑色屏幕上跳动的白色字符,我真切感受到了代码的神奇魔力。然而,学习之路并非一帆风顺。在完成实验三时,我忽略了电脑IP地址的转换,导致程序不断报错。望着满屏的红色提示,挫败感油然而生。但在老师耐心指导和同学的热心帮助下,我学会了利用调试工具逐行检查代码,终于找到问题根源。这次经历不仅让我掌握了排查错误的技巧,更培养了我面对困难时的耐心与细心。这种解决问题的能力,也悄然渗透到我日常学习中,帮助我更有条理地分析和解决复杂问题。
感谢这门Python公选课,它不仅让我掌握了一项实用技能,更打破了我对编程的固有认知。如今的我,不再畏惧代码,反而期待着用所学知识探索更多未知领域,发现新的可能。
5.参考资料
《Python程序设计》
运行过程视频
https://www.bilibili.com/video/BV1as7nzBEQj?t=11.6
源代码
import tkinter as tk
import random
class SnakeGame:
def init(self, master):
self.master = master
self.master.title("贪吃蛇")
self.width = 600
self.height = 400
self.block_size = 20
self.canvas = tk.Canvas(self.master, width=self.width, height=self.height, bg="white")
self.canvas.pack()
# 初始化游戏变量
self.snake = [(100, 100), (80, 100), (60, 100)]
self.direction = "Right"
self.next_direction = "Right"
self.food = self.create_food()
self.score = 0
self.game_over = False
# 绑定按键
self.master.bind("<Key>", self.on_key_press)
# 开始游戏
self.update()
def create_food(self):
"""随机生成食物位置"""
while True:
x = random.randint(1, (self.width - self.block_size) // self.block_size) * self.block_size
y = random.randint(1, (self.height - self.block_size) // self.block_size) * self.block_size
food_pos = (x, y)
if food_pos not in self.snake:
return food_pos
def move_snake(self):
"""移动蛇"""
head_x, head_y = self.snake[0]
if self.direction == "Up":
head_y -= self.block_size
elif self.direction == "Down":
head_y += self.block_size
elif self.direction == "Left":
head_x -= self.block_size
elif self.direction == "Right":
head_x += self.block_size
# 检查是否撞墙
if (head_x < 0 or head_x >= self.width or
head_y < 0 or head_y >= self.height):
self.game_over = True
return
# 检查是否吃到自己
new_head = (head_x, head_y)
if new_head in self.snake:
self.game_over = True
return
# 移动蛇
self.snake.insert(0, new_head)
# 检查是否吃到食物
if new_head == self.food:
self.score += 1
self.food = self.create_food()
else:
self.snake.pop()
def on_key_press(self, event):
"""处理键盘事件"""
key = event.keysym
if (key == "Up" and self.direction != "Down") or \
(key == "Down" and self.direction != "Up") or \
(key == "Left" and self.direction != "Right") or \
(key == "Right" and self.direction != "Left"):
self.next_direction = key
def update(self):
"""更新游戏状态"""
if not self.game_over:
self.direction = self.next_direction
self.move_snake()
self.draw()
self.master.after(150, self.update) # 控制游戏速度
else:
self.canvas.create_text(self.width / 2, self.height / 2,
text=f"游戏结束!分数: {self.score}",
font=("Arial", 20), fill="red")
def draw(self):
"""绘制游戏元素"""
self.canvas.delete("all")
# 绘制蛇
for segment in self.snake:
x, y = segment
self.canvas.create_rectangle(x, y, x + self.block_size, y + self.block_size,
fill="black")
# 绘制食物
x, y = self.food
self.canvas.create_oval(x, y, x + self.block_size, y + self.block_size,
fill="red")
# 显示分数
self.canvas.create_text(50, 20, text=f"分数: {self.score}",
font=("Arial", 12))
if name == "main":
root = tk.Tk()
game = SnakeGame(root)
root.mainloop()

浙公网安备 33010602011771号