20254208 2025-2026-2《Python程序设计》实验四报告
课程:《Python程序设计》
班级: 2542
姓名: 雷雨晴
学号:20254208
实验教师:王志强
实验日期:2026年5月19日
必修/选修: 专选课
1.实验内容
Python综合应用:爬虫、数据处理、可视化、机器学习、神经网络、游戏、网络安全等。
课代表和各小组负责人收集作业(源代码、视频、综合实践报告)
Python综合应用:爬虫、数据处理、可视化、机器学习、神经网络、游戏、网络安全等。
例如:编写从社交网络爬取数据,实现可视化舆情监控或者情感分析。
例如:利用公开数据集,开展图像分类、恶意软件检测等
例如:利用Python库,基于OCR技术实现自动化提取图片中数据,并填入excel中。
例如:爬取天气数据,实现自动化微信提醒
例如:利用爬虫,实现自动化下载网站视频、文件等。
例如:编写小游戏:坦克大战、贪吃蛇、扫雷等等
注:在Windows/Linux系统上使用VIM、PDB、IDLE、Pycharm等工具编程实现。
2. 实验过程及结果
以前喜欢玩谷歌无网络时的小恐龙游戏。本次实验我想自己用pygame实现一个类似的版本。
(1)为了满足程序需要,在电脑上先下载pygame

(2)使用import函数导入模块,其中random用来生成随机数,让仙人掌随机出现;sys用来关闭窗口;os用来导入最高分的文件,这样就能够知道历史最高分是多少;然后这里还用了pygame.init()启动pygame库

(3)设置游戏窗口
先设置游戏窗口,为了模仿谷歌细长的游戏画面,将游戏窗口宽度和高度分别定义为800,300像素。
然后再用screen = screen = pygame.display.set_mode((WIDTH, HEIGHT))创建这样大小的游戏窗口。
然后再用pygame.display.set_caption("谷歌小恐龙")把游戏窗口命名为谷歌小恐龙。

(4)设置颜色
再用RGB形式定义黑白两种颜色,方便后面屏幕背景(白色)和文字(黑色)调用

(5)设置游戏帧率
用clock = pygame.time.Clock()设置一个时钟,控制游戏画面的更新速度。这样游戏不会跑的太快,都没看见仙人掌小恐龙就已经撞上去了。

(6)显示最高分
用HIGH_SCORE_FILE = "highscore.txt"建立一个文档储存最高分,之后可以调用,这样就可以在玩游戏的时候看到自己现在的分数和最高分的差距了。然后建立最高分的读取和存储功能。
先定义函数读取load_high_score,如果文件存在os.path.exists(HIGH_SCORE_FILE),尝试读取其中的整数;如果是第一次玩,也就是文件不存在,则返回 0;接着定义存储save_high_score,将值转为字符串写入。

(7)选择游戏难度
定义两种仙人掌的移动速度让玩家选择,这样不同能力的玩家都可以享受游戏了。

(8)设置恐龙的代码
用self.x = 50;self.y = HEIGHT - 75;self.width = 50;self.height = 75把恐龙的初始横坐标固定在 50,纵坐标位于 HEIGHT - 75,使得它的脚刚好接触地面也就是游戏窗口的底部。
然后用self.image = pygame.image.load("dinosaur.png")
self.image = pygame.transform.scale(self.image, (self.width, self.height))把下载的恐龙照片画到游戏窗口里对应的位置,并设定照片的大小。
用self.jump_force和self.gravity设置小恐龙每次起跳向上和向下的程度,
用vel_y定义垂直速度。并定义update函数,根据速度更新小恐龙的位置,当恐龙落回地面或更低时,将纵坐标定为HEIGHT - 75,让小恐龙一接触地面就不往下落了,这样恐龙不会掉到地面下面去。
再用is_jumping,并定义函数jump防止在空中起跳,恐龙越飞越高。

(9)设置仙人掌代码
同样地设置仙人掌的代码。仙人掌初始生成在窗口最右边,然后每帧的位置是前一帧的坐标减去玩家选择的难度对应的速度。

(10)结束游戏
当恐龙撞到仙人掌的时候游戏结束。因为恐龙和仙人掌的图片都是长方形的,所有就用恐龙图片的矩形区域与仙人掌的矩形区域在 X 轴和 Y 轴上同时重叠来近似判断恐龙撞到了仙人掌。

(11)设置玩家选择难度的界面
用font = pygame.font.SysFont(None, 50)创建一个大小为50像素的系统默认字体,以供后续调用。然后调用这个字体呈现提示文字Press E for EASY | H for HARD,然后用pygame.display.update()把绘制好的画面更新到屏幕上。
接下来用for event in pygame.event.get():处理玩家的操作:
点击窗口关闭按钮——退出程序(刚刚打开没选难度就不想玩了),英文输入法点击E/H——选择对应难度

(12)设置游戏结算界面
同理用font = pygame.font.SysFont创建两种大小的字体,显示Game Over、最终分数、历史最高分、要不要按R重开一局等等提示,并用同样的方法设置关闭窗口的功能(玩玩几局不想玩了)

(13)串联以上模块,完成主游戏逻辑
先用global_high_score = load_high_score()读取历史最高分,再建立每局循环。

接下来初始化本局游戏,包括建立一个新的恐龙(没有初速度)、存放仙人掌的列表(一开始一个仙人掌都没有,这样上一局的障碍物不会保留下来)、初始得分0、游戏结束标志(一开始是False,没有结束)、spawn_timer(记录前一个仙人掌生成之后过了多久,通过让这个数随机,来随机距离地生成仙人掌)、最高分

接下来分别处理游戏中的事件
用for event in pygame.event.get()处理关闭窗口退出,按空格键跳跃

用screen.fill(WHITE)填充白色背景
用random.randint生成随机数,并调用之前的spawn_timer,当间隔时间达到随机数就生成一个仙人掌。
用dino.update()和dino.draw()每帧更新恐龙的位置并绘制。

如果恐龙越过仙人掌(仙人掌移动到恐龙的横坐标没有发生碰撞)就加一分;如果分数超过了历史最高分,历史最高分就根据目前的分数增长。

碰撞发生游戏结束

在游戏界面上绘制分数与历史最高分,同时按固定频率(60帧更新画面)

最后用game_over_screen(score, global_high_score),发生碰撞之后显示结算界面
用if name == "main":game()让运行这个文件的时候开始游戏。
源代码如下
点击查看代码
import pygame
import random
import sys
import os
# 20254208雷雨晴
pygame.init()
# 20254208雷雨晴
WIDTH, HEIGHT = 800, 200
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("谷歌小恐龙")
# 20254208雷雨晴
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
clock = pygame.time.Clock()
FPS = 60
# 20254208雷雨晴
HIGH_SCORE_FILE = "highscore.txt"
def load_high_score():
if os.path.exists(HIGH_SCORE_FILE):
with open(HIGH_SCORE_FILE, "r", encoding="utf-8") as f:
return int(f.read().strip())
return 0
def save_high_score(score):
with open(HIGH_SCORE_FILE, "w", encoding="utf-8") as f:
f.write(str(score))
EASY_SPEED = 6
HARD_SPEED = 12
class Dinosaur:
def __init__(self):
self.x = 50
self.y = HEIGHT - 75
self.width = 50
self.height = 75
self.jump_force = 15
self.gravity = 1
self.vel_y = 0
self.is_jumping = False
self.image = pygame.image.load("dinosaur.png")
self.image = pygame.transform.scale(self.image, (self.width, self.height))
# 20254208雷雨晴
def jump(self):
if not self.is_jumping:
self.is_jumping = True
self.vel_y = -self.jump_force
#20254208雷雨晴
def update(self):
if self.is_jumping:
self.y += self.vel_y
self.vel_y += self.gravity
if self.y >= HEIGHT - 75:
self.y = HEIGHT - 75
self.is_jumping = False
self.vel_y = 0
def draw(self):
screen.blit(self.image, (self.x, self.y))
class Cactus:
def __init__(self, speed):
self.x = WIDTH
self.y = HEIGHT - 40
self.width = 20
self.height = 40
self.speed = speed
self.image = pygame.image.load("cactus.png")
self.image = pygame.transform.scale(self.image, (self.width, self.height))
# 20254208雷雨晴
def update(self):
self.x -= self.speed
# 20254208雷雨晴
def draw(self):
screen.blit(self.image, (self.x, self.y))
def is_collision(dino, cactus):
if (dino.x < cactus.x + cactus.width and
dino.x + dino.width > cactus.x and
dino.y < cactus.y + cactus.height and
dino.y + dino.height > cactus.y):
return True
return False
# 20254208雷雨晴
def choose_difficulty():
font = pygame.font.SysFont(None, 50)
while True:
screen.fill(WHITE)
text1 = font.render("Press E for EASY | H for HARD", True, BLACK)
screen.blit(text1, (WIDTH//2 - 220, HEIGHT//2 - 40))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_e:
return EASY_SPEED
if event.key == pygame.K_h:
return HARD_SPEED
def game_over_screen(score, high_score):
(None, 40)
font_large = pygame.font.SysFont(None, 60)
while True:
screen.fill(WHITE)
game_over_text = font_large.render("Game Over", True, BLACK)
final_score = font.render(f"Final Score: {score}", True, BLACK)
best_score = font.render(f"History Best: {high_score}", True, BLACK)
restart_text = font.render("Press R to RESTART", True, BLACK)
screen.blit(game_over_text, (WIDTH // 2 - 100, HEIGHT // 2 - 50))
screen.blit(final_score, (WIDTH // 2 - 100, HEIGHT // 2))
screen.blit(best_score, (WIDTH // 2 - 100, HEIGHT // 2 + 30))
screen.blit(restart_text, (WIDTH // 2 - 100, HEIGHT // 2 + 60))
#20254208雷雨晴
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN and event.key == pygame.K_r:
return
def game():
global_high_score = load_high_score()
while True:
cactus_speed = choose_difficulty()
dino = Dinosaur()#20254208雷雨晴
cacti = []
score = 0
game_over = False
spawn_timer = 0
current_best = global_high_score
while not game_over:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()#20254208雷雨晴
if event.type == pygame.KEYDOWN:
if (event.key == pygame.K_SPACE or event.key == pygame.K_UP):
dino.jump()
screen.fill(WHITE)
#20254208雷雨晴
spawn_timer += 1
if spawn_timer > random.randint(40, 100):
cacti.append(Cactus(cactus_speed))
spawn_timer = 0
# 更新绘制恐龙
dino.update()
dino.draw()
#20254208雷雨晴
for cactus in cacti[:]:
cactus.update()
cactus.draw()
if cactus.x + cactus.width < 0:
cacti.remove(cactus)
score += 1
if score > current_best:
current_best = score
global_high_score = current_best
save_high_score(global_high_score)
for cactus in cacti:
if is_collision(dino, cactus):
game_over = True#20254208雷雨晴
font = pygame.font.SysFont(None, 40)
score_text = font.render(f"Score: {score}", True, BLACK)
best_text = font.render(f"Best: {current_best}", True, BLACK)
screen.blit(score_text, (10, 10))
screen.blit(best_text, (200, 10))#20254208雷雨晴
pygame.display.update()
clock.tick(FPS)
game_over_screen(score, global_high_score)
if __name__ == "__main__":
game()
3. 实验过程中遇到的问题和解决过程
问题1:无法安装pygame
- 问题1解决方案:
请教了老师,发现电脑中安装了两个python解释器,相互冲突,经老师帮助后应用了正确的解释器,成功安装。(谢谢王老师!!!d=====(≧▽≦*)b)
问题2:游戏闪退
- 问题2解决方案:询问AI,发现原来是游戏运行的太快了,仙人掌直接撞到恐龙上了。加入clock = pygame.time.Clock()等代码控制游戏帧率,让游戏以稳定速度运行。
问题3:最终界面只呈现了部分文字

- 问题3解决方案:发现呈现不了中文,将代码改成英文
![image]()
![image]()
![image]()
问题4:同学试玩游戏的时候直接连击空格键,恐龙一直往上跳,进入飞行模式,打出超高分数,地上仙人掌的障碍完全没有意义了…
- 问题4解决方案:设置变量is_jumping,让恐龙在空中的时候没有办法起跳。
![image]()
其他(感悟、思考等)
(1)实验总结:
本次实验让我们自己选择题目来编写,一开始没有老师的引导,我有点不知道应该做什么,很担心自己的想法不具备可实现性,一开始安装pygame失败时没有老师一步步的指引也特别没有头绪。但通过本次实验,对如何运用python有了更加切实的感受,既尝试调用学到的东西,也学到了很多新的知识。最重要的是通过这次实验我完整的体验了通过python提出问题和解决问题的过程,对运用python解决问题没那么迷茫无措了。收获真的特别大ヾ(≧ ▽ ≦)ゝ!
(2)全课程总结:
这学期的python课我真的学到了特别多。
首先是python的基础知识,比如列表、字典、逻辑循环、判断、随机数等等功能。作为一名文科生,我之前对python几乎没有任何了解,唯一的接触就是按图索骥地用vscode改过游戏抽卡概率,但完全不能理解代码的意思,也不知道啥是python。通过这学期的学习,我对python的开发环境、基本语法、简单函数、流程控制等等都有了比较系统性的了解,特别感谢王老师细心全面的讲解和帮助,老师课堂提问的方式也极大地帮助了我们复习巩固学过的知识。现在我终于能够看懂一些代码,也能够编写一些简单程序。实在是非常有用的技能啊!♪(∇*)
其次,python课也极大地磨练了我的耐心和细心。对我们初学者而言,编写程序的过程中的报错是不可避免的,要反复回顾,调试,尝试去用不同方法解决问题。其实很多时候,我并不确定能否仅凭自己的能力解决这些问题,但是python课极大锻炼了我的耐心,让我愿意通过多种方式慢慢尝试。同时编程的过程细心也特别重要,我们最容易犯的错误就是输入法中英文切换的问题,还有缩进,或者忘记冒号等等,通过这学期的学习,我也能够较长时间保持专注的能力,报错的次数也越来越少了。
最后,关于AI。AI的确降低了我们编写代码的门槛,但是如果我们不主动掌握编程技能,一方面可能无法应对实际应用中千奇百怪的问题(比如无法安装pygame,又比如实验四中遇到的恐龙上天问题),另一方面,这让我想起某个杂志上看到的黑箱问题:如果我们只知道人工智能输入和输出的结果,不了解这个系统运行的原理,其结果在可信度上,以及伦理上就可能存在巨大隐患。因此得加油努力学习,不能依赖AI:)
(3)意见和建议:
课程设计真的特别特别棒,唯一要说的可能就是socket部分,因为大家电脑不一样,修改IP地址的入口也不一样。当时我找了很久很久,才在网络和Internet——属性——WLAN——硬件属性——更多适配器里找到,因为这一步的卡顿也有点没跟上老师上课的节奏,建议可以在这一节课前提供一些相关资料供大家预习。
最后的最后,真的特别感谢王老师,非常耐心非常包容,课程设计对文科生也特别友好,真的太喜欢上王老师的python课了!





浙公网安备 33010602011771号