20254323 2025-2026-2 《Python程序设计》实验四报告

课程:《Python程序设计》
班级: 2543
姓名: 向俊达
学号: 20254323
实验教师:王志强
实验日期:2026年5月25日
必修/选修: 公选课

一、实验内容

Python综合应用:爬虫、数据处理、可视化、机器学习、神经网络、游戏、网络安全等。
课代表和各小组负责人收集作业(源代码、视频、综合实践报告)

Python综合应用:爬虫、数据处理、可视化、机器学习、神经网络、游戏、网络安全等。
例如:编写从社交网络爬取数据,实现可视化舆情监控或者情感分析。
例如:利用公开数据集,开展图像分类、恶意软件检测等
例如:利用Python库,基于OCR技术实现自动化提取图片中数据,并填入excel中。
例如:爬取天气数据,实现自动化微信提醒
例如:利用爬虫,实现自动化下载网站视频、文件等。
例如:编写小游戏:坦克大战、贪吃蛇、扫雷等等
注:在Windows/Linux系统上使用VIM、PDB、IDLE、Pycharm等工具编程实现。

二、实验分析与需求设计

2.1 功能需求分析

本次贪吃蛇游戏设计不少于 5 项核心功能,满足评分功能要求:
  1. 方向操控:上下左右方向键控制蛇身移动,禁止反向直接撞击。
  2. 进食成长计分:触碰食物蛇身变长,实时累加游戏分数。
  3. 死亡判定机制:触碰边界、自身身体判定游戏结束。
  4. 广告复活功能:死亡后按 W 键观看 5 秒(可具体调整)广告,保留分数与蛇身复活继续游戏。
  5. 游戏重置退出:空格键重新开局,Q 键一键关闭游戏。
  6. 界面提示交互:游戏结束弹窗提示操作按键,广告界面展示文字倒计时。

2.2 整体设计思路

  1. 界面层:初始化游戏窗口、背景配色,绘制蛇头、食物、分数、提示文字。
  2. 控制层:绑定键盘按键事件,编写方向切换、重启、复活、退出响应函数。
  3. 逻辑层:循环刷新游戏画面,实现蛇移动、食物随机生成、碰撞检测。
  4. 拓展层:新增广告倒计时页面,实现死亡复活、游戏状态切换功能。

2.3 程序结构设计

  1. 窗口与游戏元素初始化模块
  2. 键盘按键监听与操控函数模块
  3. 蛇移动、食物生成基础逻辑模块
  4. 碰撞死亡判定模块
  5. 广告展示、复活重启模块
  6. 主循环运行模块

三、程序实现过程

3.1 核心技术运用

  1. turtle 图形库:绘制游戏画面、动态图形、文字提示,实现可视化交互界面。
  2. random 随机库:随机生成食物坐标,避免刷新在蛇身位置。
  3. 事件监听:捕获键盘按键指令,触发对应游戏行为。
  4. 函数封装:将移动、判定、复活功能拆分函数,代码简洁易维护。
  5. 循环与分支:主循环实时刷新画面,if 语句完成碰撞、方向合法性判断。

3.2 关键功能实现说明

  1. 基础游玩逻辑:蛇初始位于屏幕中心,按下方向键开始移动,吃到红色食物身体增加一节,分数同步上涨;食物自动刷新空白区域,不会重叠蛇体。
  2. 死亡判定逻辑:蛇触碰窗口边界、头部撞击自身身体,立即终止游戏运行,弹出结束操作提示。
  3. 广告复活逻辑:游戏结束按下 W 键,跳转广告页面,同步显示广告位招租与 5 秒倒计时;计时结束后蛇回归屏幕中心,保留原有分数与身体长度,等待按键继续游戏。
  4. 重置与退出逻辑:空格键清空分数、重置蛇体,全新开局游玩;按下 Q 键直接关闭游戏窗口,结束程序。
游戏窗口初始化
import turtle
import random
import time

win = turtle.Screen()
win.title("Python 贪吃蛇游戏")
win.bgcolor("#1a1a1a")
win.setup(width=600, height=600)
win.tracer(0)

蛇头初始化

head = turtle.Turtle()
head.speed(0)
head.shape("square")
head.color("#00ff00")
head.penup()
head.goto(0, 0)
head.direction = "stop"

食物初始化

food = turtle.Turtle()
food.speed(0)
food.shape("circle")
food.color("#ff4444")
food.penup()

segments = []
score = 0

分数绘制画笔

pen = turtle.Turtle()
pen.speed(0)
pen.color("white")
pen.penup()
pen.hideturtle()
pen.goto(0, 260)
pen.write(f"分数: {score}", align="center", font=("Arial", 24, "bold"))

提示文字画笔

tip_pen = turtle.Turtle()
tip_pen.speed(0)
tip_pen.color("white")
tip_pen.penup()
tip_pen.hideturtle()

广告绘制画笔

ad_pen = turtle.Turtle()
ad_pen.speed(0)
ad_pen.color("yellow")
ad_pen.penup()
ad_pen.hideturtle()

可以直接在pycharm上运行的独立游戏窗口

image

方向控制与移动
def go_up():
    if head.direction == "stop":
        head.direction = "up"
    elif head.direction != "down":
        head.direction = "up"

def go_down():
if head.direction == "stop":
head.direction = "down"
elif head.direction != "up":
head.direction = "down"

def go_left():
if head.direction == "stop":
head.direction = "left"
elif head.direction != "right":
head.direction = "left"

def go_right():
if head.direction == "stop":
head.direction = "right"
elif head.direction != "left":
head.direction = "right"

蛇移动函数

def move():
if head.direction == "up":
head.sety(head.ycor() + 20)
if head.direction == "down":
head.sety(head.ycor() - 20)
if head.direction == "left":
head.setx(head.xcor() - 20)
if head.direction == "right":
head.setx(head.xcor() + 20)


随机生成食物

def new_food():
    while True:
        x = random.randint(-280, 280)
        y = random.randint(-280, 280)
        x = round(x / 20) * 20
        y = round(y / 20) * 20
        pos = (x, y)
        snake_pos = [(s.xcor(), s.ycor()) for s in segments]
        if pos not in snake_pos and pos != (head.xcor(), head.ycor()):
            food.goto(x, y)
            break

广告复活功能

def watch_ad():
    tip_pen.clear()
    ad_pen.clear()
    old_bg = win.bgcolor()
    win.bgcolor("#000011")
    # 广告文字与倒计时同步显示
    for cnt in range(5, 0, -1):
        ad_pen.clear()
        ad_pen.goto(0, 100)
        ad_pen.write("广告位招租", align="center", font=("simhei", 60, "bold"))
        ad_pen.goto(0, -100)
        ad_pen.write(f"倒计时 {cnt} 秒", align="center", font=("simhei", 40))
        win.update()
        time.sleep(1)
    # 广告消失恢复游戏
    ad_pen.clear()
    win.bgcolor(old_bg)
    head.goto(0, 0)
    head.direction = "stop"
    win.update()
    # 蛇身缓慢复原
    import threading
    def grow_body():
        time.sleep(0.5)
        temp = []
        for i in range(len(segments)):
            temp.append(segments.pop())
        while temp:
            segments.append(temp.pop())
            win.update()
            time.sleep(0.2)
        game_loop()
    threading.Thread(target=grow_body, daemon=True).start()

# 游戏重置
def reset_game():
    global segments, score
    head.goto(0, 0)
    head.direction = "stop"
    for seg in segments:
        seg.hideturtle()
    segments.clear()
    score = 0
    pen.clear()
    pen.write(f"分数: {score}", align="center", font=("Arial", 24, "bold"))
    tip_pen.clear()
    new_food()
    game_loop()

image

退出游戏与游戏结束提示
def quit_game():
    turtle.bye()

游戏结束提示

def show_gameover():
tip_pen.clear()
tip_pen.goto(0, 120)
tip_pen.write("游戏结束!", align="center", font=("simhei", 40, "bold"))
tip_pen.goto(0, 60)
tip_pen.write("按 W 观看广告复活", align="center", font=("simhei", 26))
tip_pen.goto(0, 20)
tip_pen.write("按 空格 重新开局", align="center", font=("simhei", 26))
tip_pen.goto(0, -20)
tip_pen.write("按 Q 退出游戏", align="center", font=("simhei", 26))
win.update()

image

游戏主循环
def game_loop():
    global score
    win.update()
    # 撞墙判定
    if head.xcor() > 290 or head.xcor() < -290 or head.ycor() > 290 or head.ycor() < -290:
        show_gameover()
        return
    # 进食加分
    if head.distance(food) < 15:
        new_segment = turtle.Turtle()
        new_segment.speed(0)
        new_segment.shape("square")
        new_segment.color("#00cc00")
        new_segment.penup()
        segments.append(new_segment)
        score += 10
        pen.clear()
        pen.write(f"分数: {score}", align="center", font=("Arial", 24, "bold"))
        new_food()
    # 蛇身跟随移动
    for i in range(len(segments)-1, 0, -1):
        segments[i].goto(segments[i-1].xcor(), segments[i-1].ycor())
    if segments:
        segments[0].goto(head.xcor(), head.ycor())
    move()
    # 自身碰撞判定
    for seg in segments:
        if seg.distance(head) < 15:
            show_gameover()
            return
    win.ontimer(game_loop, 80)

3.3 完整源代码

源代码
import turtle
import random
import time

win = turtle.Screen()
win.title("Python 贪吃蛇游戏")
win.bgcolor("#1a1a1a")
win.setup(width=600, height=600)
win.tracer(0)

head = turtle.Turtle()
head.speed(0)
head.shape("square")
head.color("#00ff00")
head.penup()
head.goto(0, 0)
head.direction = "stop"

food = turtle.Turtle()
food.speed(0)
food.shape("circle")
food.color("#ff4444")
food.penup()

segments = []
score = 0

pen = turtle.Turtle()
pen.speed(0)
pen.color("white")
pen.penup()
pen.hideturtle()
pen.goto(0, 260)
pen.write(f"分数: {score}", align="center", font=("Arial", 24, "bold"))

tip_pen = turtle.Turtle()
tip_pen.speed(0)
tip_pen.color("white")
tip_pen.penup()
tip_pen.hideturtle()

ad_pen = turtle.Turtle()
ad_pen.speed(0)
ad_pen.color("yellow")
ad_pen.penup()
ad_pen.hideturtle()

def go_up():
if head.direction == "stop":
head.direction = "up"
elif head.direction != "down":
head.direction = "up"

def go_down():
if head.direction == "stop":
head.direction = "down"
elif head.direction != "up":
head.direction = "down"

def go_left():
if head.direction == "stop":
head.direction = "left"
elif head.direction != "right":
head.direction = "left"

def go_right():
if head.direction == "stop":
head.direction = "right"
elif head.direction != "left":
head.direction = "right"

def move():
if head.direction == "up":
head.sety(head.ycor() + 20)
if head.direction == "down":
head.sety(head.ycor() - 20)
if head.direction == "left":
head.setx(head.xcor() - 20)
if head.direction == "right":
head.setx(head.xcor() + 20)

def new_food():
while True:
x = random.randint(-280, 280)
y = random.randint(-280, 280)
x = round(x / 20) * 20
y = round(y / 20) * 20
pos = (x, y)
snake_pos = [(s.xcor(), s.ycor()) for s in segments]
if pos not in snake_pos and pos != (head.xcor(), head.ycor()):
food.goto(x, y)
break

def watch_ad():
tip_pen.clear()
ad_pen.clear()
old_bg = win.bgcolor()
win.bgcolor("#000011")

for cnt in range(5, 0, -1):
ad_pen.clear()
ad_pen.goto(0, 100)
ad_pen.write("广告位招租", align="center", font=("simhei", 60, "bold"))
ad_pen.goto(0, -100)
ad_pen.write(f"倒计时 {cnt} 秒", align="center", font=("simhei", 40))
win.update()
time.sleep(1)

ad_pen.clear()
win.bgcolor(old_bg)
head.goto(0, 0)
head.direction = "stop"
win.update()

import threading
def grow_body():
time.sleep(0.5)
temp = []
for i in range(len(segments)):
temp.append(segments.pop())
while temp:
segments.append(temp.pop())
win.update()
time.sleep(0.2)
game_loop()

threading.Thread(target=grow_body, daemon=True).start()

def reset_game():
global segments, score
head.goto(0, 0)
head.direction = "stop"
for seg in segments:
seg.hideturtle()
segments.clear()
score = 0
pen.clear()
pen.write(f"分数: {score}", align="center", font=("Arial", 24, "bold"))
tip_pen.clear()
new_food()
game_loop()

def quit_game():
turtle.bye()

def show_gameover():
tip_pen.clear()
tip_pen.goto(0, 120)
tip_pen.write("游戏结束!", align="center", font=("simhei", 40, "bold"))
tip_pen.goto(0, 60)
tip_pen.write("按 W 观看广告复活", align="center", font=("simhei", 26))
tip_pen.goto(0, 20)
tip_pen.write("按 空格 重新开局", align="center", font=("simhei", 26))
tip_pen.goto(0, -20)
tip_pen.write("按 Q 退出游戏", align="center", font=("simhei", 26))
win.update()

def game_loop():
global score
win.update()

if head.xcor() > 290 or head.xcor() < -290 or head.ycor() > 290 or head.ycor() < -290:
show_gameover()
return

if head.distance(food) < 15:
new_segment = turtle.Turtle()
new_segment.speed(0)
new_segment.shape("square")
new_segment.color("#00cc00")
new_segment.penup()
segments.append(new_segment)
score += 10
pen.clear()
pen.write(f"分数: {score}", align="center", font=("Arial", 24, "bold"))
new_food()

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

move()

for seg in segments:
if seg.distance(head) < 15:
show_gameover()
return

win.ontimer(game_loop, 80)

win.listen()
win.onkeypress(go_up, "Up")
win.onkeypress(go_down, "Down")
win.onkeypress(go_left, "Left")
win.onkeypress(go_right, "Right")
win.onkeypress(quit_game, "q")
win.onkeypress(reset_game, "space")
win.onkeypress(watch_ad, "w")

启动

new_food()
game_loop()
win.mainloop()

四、实验运行结果

  1. 程序启动:代码运行直接弹出游戏窗口,深色背景界面完整展示蛇头与初始食物,程序无报错、闪退问题。
  2. 基础游玩:方向键操控移动,顺利吃掉食物,蛇身变长,分数实时上涨。
  3. 死亡效果:撞墙、撞到自身后游戏停止,界面弹出操作提示文字。
  4. 广告复活:按下 W 键弹出广告页面,广告文字与 5 秒倒计时同步显示,计时结束成功保留数据复活游戏。
  5. 重置退出:空格键可清空数据重新游玩,Q 键正常关闭程序,所有功能均可稳定运行。
  6. 额外录制程序运行视频,完整记录游戏操作、功能触发全过程,佐证程序可用性。
游戏演示视频:

若上方视频无法播放(备用选项):点击播放

五、课程整体总结与心得体会

5.1 课程知识总结

本学期的 Python 课程里,我循序渐进完成了全部知识学习,整体分为三大板块:
  1. 基础语法板块:掌握变量、数据类型、运算符、分支 if、循环 for/while、列表字典等容器用法,学会基础输入输出代码编写,搭建编程思维。
  2. 进阶编程板块:学习函数定义调用、参数传递、异常处理、文件读写,能够拆分功能模块,优化代码结构,提升程序可读性。
  3. 综合应用板块:接触第三方库使用,涵盖图形游戏开发、爬虫基础、数据简单处理等方向,了解 Python 在多领域的实际用途,具备小型综合程序开发能力。

5.2 学习心得体会

通过本学期 Python 课程的系统学习,在王志强老师的悉心授课指导下,我从零基础入门,逐步理解编程逻辑与代码思维。最初编写简单代码时常出现缩进错误、语法拼写失误,经过反复调试练习,现在能够独立分析需求、拆分功能、编写完整程序。
学习期间,我夯实了基础编程逻辑,能够运用 Python 代码处理日常问题,切实提升了自身编程实操水平。同时,我养成了严谨规范的编程思维,编写代码时会主动规避死循环、输入异常、数据异常等常见问题,规范变量命名与代码书写格式,熟练掌握报错分析、代码调试、漏洞排查的技巧,熟悉了从需求分析、框架搭建到功能落地的整套项目开发流程。

5.3 课程意见与建议

结合自身学习感受,也给老师的课堂教学提一点小小的建议。部分知识点可以适当放慢讲解节奏,像代码托管平台这类工具操作内容,我们大一新生初次接触普遍比较生疏,理解起来存在难度。纯代码语法知识更容易理解吸收;课后可以布置分层练习,基础题巩固语法,拓展题偏向游戏、爬虫趣味项目,提升学习积极性。

 
posted @ 2026-05-25 21:26  Moonshot-_-  阅读(29)  评论(0)    收藏  举报