20244102 实验四《Python程序设计》实验报告
课程:《Python程序设计》
班级: 2441
姓名: 丁可
学号:20244102
实验教师:王志强
实验日期:2025年5月29日
必修/选修: 公选课
一、实验内容
Python综合应用:爬虫、数据处理、可视化、机器学习、神经网络、游戏、网络安全等。
在日常的生活中,需要游戏来解压,于是我编写了小游戏:贪吃蛇!!!
二、实验过程
(一)搭建游戏框架
1.导入所需的库:
点击查看代码
import pygame
import time
import random
点击查看代码
pygame.init()
点击查看代码
window_width = 800
window_height = 600
game_window = pygame.display.set_mode((window_width, window_height))
pygame.display.set_caption("贪吃蛇游戏")
点击查看代码
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
green = (0, 255, 0)
font = pygame.font.SysFont('arial', 50)
点击查看代码
class Snake:
def __init__(self):
self.body = [[10, 10], [9, 10], [8, 10]] # 初始身体位置,头部在[10,10]
self.direction = 'RIGHT' # 初始方向向右
self.next_direction = 'RIGHT' # 下一个方向,用于防止反向移动
点击查看代码
def move(self):
self.next_direction = self.direction # 更新下一个方向为当前方向
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT and self.direction != 'RIGHT':
self.next_direction = 'LEFT'
elif event.key == pygame.K_RIGHT and self.direction != 'LEFT':
self.next_direction = 'RIGHT'
elif event.key == pygame.K_UP and self.direction != 'DOWN':
self.next_direction = 'UP'
elif event.key == pygame.K_DOWN and self.direction != 'UP':
self.next_direction = 'DOWN'
self.direction = self.next_direction # 更新当前方向为下一个方向
head = self.body[0].copy() # 获取当前头部位置
if self.direction == 'RIGHT':
head[0] += 1
elif self.direction == 'LEFT':
head[0] -= 1
elif self.direction == 'UP':
head[1] -= 1
elif self.direction == 'DOWN':
head[1] += 1
self.body.insert(0, head) # 将新头部插入身体列表开头
点击查看代码
def grow(self):
pass # 因为在移动时,只有在没吃到食物时才移除蛇尾,所以增长通过不移除蛇尾实现
点击查看代码
def check_collision(self):
head = self.body[0]
# 检测边界碰撞
if head[0] < 0 or head[0] >= 40 or head[1] < 0 or head[1] >= 30:
return True
# 检测自身碰撞
for segment in self.body[1:]:
if head == segment:
return True
return False
点击查看代码
class Food:
def __init__(self, snake_body):
self.position = self.generate_position(snake_body)
def generate_position(self, snake_body):
while True:
x = random.randint(0, 39)
y = random.randint(0, 29)
if [x, y] not in snake_body:
return [x, y]
点击查看代码
snake = Snake()
food = Food(snake.body)
点击查看代码
score = 0
speed = 150 # 初始速度,单位为毫秒/步
点击查看代码
game_over = False
while not game_over:
game_window.fill(black) # 填充背景颜色
# 处理事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
# 移动蛇
snake.move()
# 检测是否吃到食物
head = snake.body[0]
if head == food.position:
score += 10
speed -= 20 # 加快速度
snake.body.append([-1, -1]) # 添加一个无效位置,用于增长,实际在移动时不会移除
food = Food(snake.body) # 生成新食物
# 检测碰撞
if snake.check_collision():
game_over = True
# 绘制蛇
for segment in snake.body:
pygame.draw.rect(game_window, green, (segment[0] * 20, segment[1] * 20, 20, 20))
# 绘制食物
pygame.draw.rect(game_window, red, (food.position[0] * 20, food.position[1] * 20, 20, 20))
# 显示分数
score_text = font.render("分数: " + str(score), True, white)
game_window.blit(score_text, (10, 10))
pygame.display.update() # 更新画面
time.sleep(speed / 1000) # 控制游戏速度
点击查看代码
game_over_text = font.render("游戏结束!分数: " + str(score), True, red)
game_window.blit(game_over_text, (window_width // 2 - 200, window_height // 2 - 50))
pygame.display.update()
time.sleep(3) # 等待3秒后退出
点击查看代码
import pygame
import time
import random
pygame.init()
window_width = 800
window_height = 600
game_window = pygame.display.set_mode((window_width, window_height))
pygame.display.set_caption("贪吃蛇游戏")
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
green = (0, 255, 0)
font = pygame.font.SysFont('arial', 50)
class Snake:
def __init__(self):
self.body = [[10, 10], [9, 10], [8, 10]] # 初始身体位置,头部在[10,10]
self.direction = 'RIGHT' # 初始方向向右
self.next_direction = 'RIGHT' # 下一个方向,用于防止反向移动
def move(self):
# 移除了这里的事件处理,改为在主循环中统一处理
self.direction = self.next_direction # 更新当前方向为下一个方向
head = self.body[0].copy() # 获取当前头部位置
if self.direction == 'RIGHT':
head[0] += 1
elif self.direction == 'LEFT':
head[0] -= 1
elif self.direction == 'UP':
head[1] -= 1
elif self.direction == 'DOWN':
head[1] += 1
self.body.insert(0, head) # 将新头部插入身体列表开头
def grow(self):
pass # 因为在移动时,只有在没吃到食物时才移除蛇尾,所以增长通过不移除蛇尾实现
def check_collision(self):
head = self.body[0]
# 检测边界碰撞
if head[0] < 0 or head[0] >= 40 or head[1] < 0 or head[1] >= 30:
return True
# 检测自身碰撞
for segment in self.body[1:]:
if head == segment:
return True
return False
class Food:
def __init__(self, snake_body):
self.position = self.generate_position(snake_body)
def generate_position(self, snake_body):
while True:
x = random.randint(0, 39)
y = random.randint(0, 29)
if [x, y] not in snake_body:
return [x, y]
# 游戏初始化
snake = Snake()
food = Food(snake.body)
score = 0
initial_speed = 150 # 初始速度,单位为毫秒/步
speed = initial_speed
game_over = False
# 游戏时钟,用于控制帧率
clock = pygame.time.Clock()
while not game_over:
# 处理事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
elif event.type == pygame.KEYDOWN:
# 在主循环中统一处理方向键
if event.key == pygame.K_LEFT and snake.direction != 'RIGHT':
snake.next_direction = 'LEFT'
elif event.key == pygame.K_RIGHT and snake.direction != 'LEFT':
snake.next_direction = 'RIGHT'
elif event.key == pygame.K_UP and snake.direction != 'DOWN':
snake.next_direction = 'UP'
elif event.key == pygame.K_DOWN and snake.direction != 'UP':
snake.next_direction = 'DOWN'
# 移动蛇
snake.move()
# 检测是否吃到食物
head = snake.body[0]
if head == food.position:
score += 10
# 调整速度的方式更合理,避免过快
speed = max(50, initial_speed - score // 10 * 5)
# 添加一个无效位置,用于增长,实际在移动时不会移除
snake.body.append([-1, -1])
food = Food(snake.body) # 生成新食物
else:
# 如果没吃到食物,移除尾部
snake.body.pop()
# 检测碰撞
if snake.check_collision():
game_over = True
# 绘制游戏元素
game_window.fill(black) # 填充背景颜色
# 绘制蛇
for segment in snake.body:
pygame.draw.rect(game_window, green, (segment[0] * 20, segment[1] * 20, 20, 20))
# 绘制食物
pygame.draw.rect(game_window, red, (food.position[0] * 20, food.position[1] * 20, 20, 20))
# 显示分数和速度
score_text = font.render(f"分数: {score}", True, white)
speed_text = font.render(f"速度: {1000 // speed:.1f} FPS", True, white)
game_window.blit(score_text, (10, 10))
game_window.blit(speed_text, (10, 60))
pygame.display.update() # 更新画面
# 使用pygame的时钟控制帧率,替代原来的time.sleep
clock.tick(1000 / speed)
# 游戏结束画面
game_over_text = font.render(f"游戏结束!分数: {score}", True, red)
game_window.blit(game_over_text, (window_width // 2 - 200, window_height // 2 - 50))
pygame.display.update()
time.sleep(3) # 等待3秒后退出
(五)程序运行
【屏幕录制 2025-05-29 212353】 https://www.bilibili.com/video/BV1MH75zjEHa/?share_source=copy_web&vd_source=1b8c219f085f846d6b50bcb3aedd408b
三、问题总结
1.发现了我的pycharm缺少pygame库。于是我手动安装了!!!!

2.发现还是不行,是虚拟环境创建失败。于是我创建虚拟环境。

3.好不容易上两个问题解决了,结果运行的时候发现我的贪吃蛇不受我控制,我的键盘不管用。老师您估计也发现我的完整代码和前面的步骤有所不同了。后来我才发现方向键控制逻辑被重复实现了,导致部分按键失效。问题出在 Snake.move() 方法中处理了按键事件,但主循环中也处理了事件。这导致按键可能被主循环捕获而不是蛇的移动逻辑。于是我移除重复的事件处理,并确保方向控制更加流畅。
四、课程总结与建议
(一)实验总结
通过本次实验,我将课堂中学习的Python知识运用到了日常学习生活,激发了我学习Python语言的热情,帮助我回顾了过去学过的Python知识,也让我拓展了所学,对虚拟环境的创建、pygame安装等模块有了更深的理解。尽管遇到了些许困难,但我体会到了将课堂上的知识应用到实际的感觉,编程能力得到了很大的提高。而且这次游戏成功运行,给我带来了成就感!呜呜呜真的太不容易了,尤其是pygame这一块,我终于调整成功了!
(二)课程总结
首先,我想对您说,您是一个很和蔼可亲的老师!您讲课的方式很幽默轻松,您给我评论过朋友圈,大大拉近了我们之间的距离,我更喜欢听您的课了!您一直在给我们降低难度,充分考虑我们作为文科生的不易,并且你通过英语打卡的方式激励我们学英语,让我不再畏惧四级英语!
几周一晃就过去了,Python 课就像本打开的入门书,从打印 "Hello World" 到摆弄列表字典,再到试着写点小功能,一步一步摸着石头过河。刚开始敲代码总报错,对着屏幕改半天;后来试着用函数把重复的事打包,突然觉得程序像模像样了。我曾经对python没有一点好感,但是今天通过我的努力成功运行一个小游戏,我发现我真的爱上python啦!
感谢您这段时间的付出,听您讲课真的很轻松愉快,尽管以后没有python课,我也会继续运行一些我喜欢的程序的!毕竟真的很有意思哈哈哈哈。真的很开心遇见了您!!!!!!!!
(三)意见建议
能不能签到弄得简单一点呀,我没有一次是自己签成功的哈哈哈

浙公网安备 33010602011771号