#cnblogs_post_body .video{ height: 0; padding-bottom: 56.25%; /* 16:9 */ position: relative; width: 100%; } #cnblogs_post_body .video iframe{ position: absolute; left: 0; top: 0; width: 100%; height: 100%; }

20253307张新政《Python程序设计》实验四实验报告

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

课程:《Python程序设计》

班级: 2533

姓名: 张新政

学号: 20253307

实验教师:王志强

实验日期:2026年5月18日

必修/选修: 公选课

1.实验内容

Python综合应用:爬虫、数据处理、可视化、机器学习、神经网络、游戏、网络安全等。

课代表和各小组负责人收集作业(源代码、视频、综合实践报告)

Python综合应用:爬虫、数据处理、可视化、机器学习、神经网络、游戏、网络安全等。

例如:编写从社交网络爬取数据,实现可视化舆情监控或者情感分析。

例如:利用公开数据集,开展图像分类、恶意软件检测等

例如:利用Python库,基于OCR技术实现自动化提取图片中数据,并填入excel中。

例如:爬取天气数据,实现自动化微信提醒

例如:利用爬虫,实现自动化下载网站视频、文件等。

例如:编写小游戏:坦克大战、贪吃蛇、扫雷等等

注:在Windows/Linux系统上使用VIM、PDB、IDLE、Pycharm等工具编程实现。

评分标准:

(1)程序能运行,功能丰富(至少5个功能)。(需求提交源代码,并建议录制程序运行的视频)15分

(2)综合实践报告,要体现实验分析、设计、实现过程、结果等信息,格式规范,逻辑清晰,结构合理。20分。

(3)在实践报告中,需要对全课进行总结,并写课程感想体会、意见和建议等。10分

2.实验选题:超级玛丽2.0(游戏制作)

本地实验环境:

系统:windows11
开发语言:python3.12
集成开发环境:IDLE(python3.12 64-bit)
多媒体 / 游戏开发库:Pygame

实验设计:

本实验基于 Python 和 Pygame 开发简易超级玛丽2.0游戏,采用面向对象与模块化设计,拆分初始化、角色、场景障碍、主循环渲染四大模块。依托 Pygame 主循环机制,结合重力物理模拟、矩形碰撞检测、画面实时渲染技术,实现玛丽键盘控移、跳跃、障碍物碰撞、窗口边界限制、背景音开关、实时计时等核心功能,完成 2D 横版小游戏的基础开发与调试实践。

实验过程:

(1)搭建实验必要环境

介于pygame在较新版本pycharm不兼容,我选择使用IDLE(python3.12 64-bit)进行实验,并且在其中安装pygame库

输入代码:

import subprocess, sys 
subprocess.check_call([sys.executable, "-m", "pip", "install", "pygame", "-i", "https://pypi.tuna.tsinghua.edu.cn/simple"])

image

如图所示,输出0,下载完毕

(2)制作游戏资源(已规避版权问题)

利用ps软件手绘游戏内图像资源(包含三个主角跑动的图片,1~9的分数,水管障碍物,导弹,禁音键,扬声键):

e61261c65c57eeeaa670ac41a1293245

8b0e06023b96514478b1372180057ebc

在百度搜索公开使用的音频资源

image

(3)创建项目文件夹并放入资源文件

新建文件夹命名为MarieAdventure,
在文件夹内创建:
主代码文件:marie_game.py(游戏本体)
资源文件夹:image/(存放所有图片资源)、audio/(存放所有音效资源)

image

(4) 游戏本体代码编写

1.导入模块 + 定义全局常量

目标:搭建游戏最基础的运行环境,定义固定参数。
编写代码:

import pygame  
from pygame.locals import * 
import sys  
from itertools import cycle 
import random 

# 游戏全局常量
SCREENWIDTH = 822      # 窗口宽度
SCREENHEIGHT = 199     # 窗口高度
FPS = 30               # 游戏帧率       

步骤说明:
导入 pygame 实现游戏功能,sys 用于退出程序。
cycle 实现角色动画循环,random 实现随机障碍物。
定义窗口大小、帧率,方便统一修改游戏参数。

2.创建地图类 MyMap(实现背景滚动)

目标:实现游戏背景无限向左滚动效果。
编写代码:

class MyMap():
    def __init__(self, x, y):
        # 加载背景图
        self.bg = pygame.image.load("image/bg.png").convert_alpha()
        self.x = x
        self.y = y

    def map_rolling(self):
        # 背景移出屏幕后重置到右侧,实现无缝滚动
        if self.x < -790: 
            self.x = 800  
        else:
            self.x -= 5  

    def map_update(self, screen):
        # 将背景绘制到窗口
        screen.blit(self.bg, (self.x, self.y))

步骤说明:
init:初始化背景图片与坐标。
map_rolling:背景不断左移,超出屏幕后重置,实现循环滚动。
map_update:将图片渲染到游戏窗口。

3.创建音乐按钮类 Music_Button

目标:实现背景音乐开关、点击切换功能。
编写代码:

class Music_Button():
    is_open = True 
    def __init__(self):
        # 加载按钮图片
        self.open_img = pygame.image.load('image/btn_open.png').convert_alpha()
        self.close_img = pygame.image.load('image/btn_close.png').convert_alpha()
        # 加载背景音乐
        self.bg_music = pygame.mixer.Sound('audio/bg_music.wav')  

    # 判断鼠标是否点击按钮
    def is_select(self):
        point_x, point_y = pygame.mouse.get_pos()
        w, h = self.open_img.get_size()            
        in_x = point_x > 20 and point_x < 20 + w
        in_y = point_y > 20 and point_y < 20 + h
        return in_x and in_y

步骤说明:
使用 is_open 记录音乐状态。
加载两张按钮图片(开 / 关)。
is_select 检测鼠标是否在按钮区域内,实现点击交互。

4.创建主角类 Marie(跳跃 + 动画)

目标:实现玛丽跳跃、动画播放、跳跃音效。
编写代码:

点击查看代码
class Marie():
    def __init__(self):
        self.rect = pygame.Rect(0, 0, 0, 0)
        self.jumpState = False      # 是否跳跃中
        self.jumpHeight = 130       # 跳跃高度
        self.lowest_y = 140         # 地面位置
        self.jumpValue = 0          # 跳跃速度
        
        self.marieIndex = 0
        self.marieIndexGen = cycle([0, 1, 2])
        
        # 加载角色动画图
        self.adventure_img = (
            pygame.image.load("image/adventure1.png").convert_alpha(),
            pygame.image.load("image/adventure2.png").convert_alpha(),
            pygame.image.load("image/adventure3.png").convert_alpha(),
        )
        self.jump_audio = pygame.mixer.Sound('audio/jump.wav') 
        self.rect.size = self.adventure_img[0].get_size()
        self.x = 50
        self.y = self.lowest_y
        self.rect.topleft = (self.x, self.y)

    # 开启跳跃
    def jump(self):
        self.jumpState = True

    # 跳跃移动逻辑
    def move(self):
        if self.jumpState:  
            if self.rect.y >= self.lowest_y:  
                self.jumpValue = -5
            if self.rect.y <= self.lowest_y - self.jumpHeight:
                self.jumpValue = 5
            self.rect.y += self.jumpValue
            if self.rect.y >= self.lowest_y:
                self.jumpState = False

    # 绘制玛丽
    def draw_marie(self, screen):
        marieIndex = next(self.marieIndexGen)
        screen.blit(self.adventure_img[marieIndex], (self.x, self.rect.y))

步骤说明:
使用 rect 实现碰撞区域。
跳跃逻辑:上升 → 回落 → 落地。
使用 cycle 循环播放 3 张图片形成跑步动画。
加载跳跃音效,按空格时播放。

5:创建障碍物类 Obstacle(障碍物 + 计分)

目标:随机生成管道 / 导弹、移动、计分、得分音效。
编写代码:

点击查看代码
class Obstacle():
    score = 1
    move = 5
    obstacle_y = 150
    def __init__(self):
        self.rect = pygame.Rect(0, 0, 0, 0)
        # 加载障碍物图片
        self.missile = pygame.image.load("image/missile.png").convert_alpha()
        self.pipe = pygame.image.load("image/pipe.png").convert_alpha()
        # 加载分数图片
        self.numbers = (
            pygame.image.load('image/0.png').convert_alpha(),
            pygame.image.load('image/1.png').convert_alpha(),
            pygame.image.load('image/2.png').convert_alpha(),
            pygame.image.load('image/3.png').convert_alpha(),
            pygame.image.load('image/4.png').convert_alpha(),
            pygame.image.load('image/5.png').convert_alpha(),
            pygame.image.load('image/6.png').convert_alpha(),
            pygame.image.load('image/7.png').convert_alpha(),
            pygame.image.load('image/8.png').convert_alpha(),
            pygame.image.load('image/9.png').convert_alpha()
        )
        self.score_audio = pygame.mixer.Sound('audio/score.wav')
        
        # 随机生成障碍物
        r = random.randint(0, 1)
        if r == 0:
            self.image = self.missile
            self.move = 15
            self.obstacle_y = 100
        else:
            self.image = self.pipe
        self.rect.size = self.image.get_size()
        self.width, self.height = self.rect.size
        self.x = 800
        self.y = self.obstacle_y
        self.rect.center = (self.x, self.y)

    # 障碍物移动
    def obstacle_move(self):
        self.rect.x -= self.move

    # 绘制障碍物
    def draw_obstacle(self, screen):
        screen.blit(self.image, (self.rect.x, self.rect.y))

    # 获取分数
    def getScore(self):
        tmp = self.score
        if tmp == 1:
            self.score_audio.play()
        self.score = 0
        return tmp

    # 显示分数
    def showScore(self, screen, score):
        self.scoreDigits = [int(x) for x in list(str(score))]
        totalWidth = 0
        for digit in self.scoreDigits:
            totalWidth += self.numbers[digit].get_width()
        Xoffset = (SCREENWIDTH - (totalWidth+30))
        for digit in self.scoreDigits:
            screen.blit(self.numbers[digit], (Xoffset, SCREENHEIGHT * 0.1))
            Xoffset += self.numbers[digit].get_width()

步骤说明:
随机生成管道 / 导弹,速度与位置不同。
障碍物自动向左移动。
玛丽越过障碍物自动加分并播放音效。
将数字转为图片显示在屏幕右上角。

6.编写游戏结束函数 game_over ()

目标:碰撞后显示结束画面、播放撞击音效。
编写代码:

def game_over(screen):
    bump_audio = pygame.mixer.Sound('audio/bump.wav')
    bump_audio.play()
    screen_w = pygame.display.Info().current_w
    screen_h = pygame.display.Info().current_h
    over_img = pygame.image.load('image/gameover.png').convert_alpha()
    screen.blit(over_img, ((screen_w - over_img.get_width()) / 2,
                           (screen_h - over_img.get_height()) / 2))

步骤说明:
播放撞击音效。
加载游戏结束图片并居中显示。

7.编写主游戏函数 mainGame ()

目标:游戏主循环、事件监听、对象调用、整体逻辑控制。
编写代码:

点击查看代码
def mainGame():
    score = 0
    over = False
    global SCREEN, FPSCLOCK
    pygame.init()

    FPSCLOCK = pygame.time.Clock()
    SCREEN = pygame.display.set_mode((SCREENWIDTH, SCREENHEIGHT))
    pygame.display.set_caption('玛丽冒险')

    # 创建地图
    bg1 = MyMap(0, 0)
    bg2 = MyMap(800, 0)

    # 创建玛丽
    marie = Marie()

    addObstacleTimer = 0
    obstacle_list = []

    # 创建音乐按钮
    music_button = Music_Button()
    btn_img = music_button.open_img
    music_button.bg_music.play(-1)

    while True:
        # 获取事件
        for event in pygame.event.get():
            if event.type == pygame.MOUSEBUTTONUP:
                if music_button.is_select():
                    if music_button.is_open:
                        btn_img = music_button.close_img
                        music_button.is_open = False
                        music_button.bg_music.stop()
                    else:
                        btn_img = music_button.open_img
                        music_button.is_open = True
                        music_button.bg_music.play(-1)

            if event.type == QUIT:
                pygame.quit()
                sys.exit()

            # 空格跳跃
            if event.type == KEYDOWN and event.key == K_SPACE:
                if marie.rect.y >= marie.lowest_y and not over:
                    marie.jump_audio.play()
                    marie.jump()
                if over:
                    mainGame()

        if not over:
            # 绘制并滚动地图
            bg1.map_update(SCREEN)
            bg1.map_rolling()
            bg2.map_update(SCREEN)
            bg2.map_rolling()

            marie.move()
            marie.draw_marie(SCREEN)

            # 生成障碍物
            if addObstacleTimer >= 1300:
                r = random.randint(0, 100)
                if r > 40:
                    obstacle = Obstacle()
                    obstacle_list.append(obstacle)
                addObstacleTimer = 0

            # 遍历障碍物
            for i in range(len(obstacle_list)):
                obstacle_list[i].obstacle_move()
                obstacle_list[i].draw_obstacle(SCREEN)

                # 碰撞检测
                if pygame.sprite.collide_rect(marie, obstacle_list[i]):
                    over = True
                    game_over(SCREEN)
                    music_button.bg_music.stop()
                else:
                    if (obstacle_list[i].rect.x + obstacle_list[i].rect.width) < marie.rect.x:
                        score += obstacle_list[i].getScore()
                obstacle_list[i].showScore(SCREEN, score)

        addObstacleTimer += 20
        SCREEN.blit(btn_img, (20, 20))
        pygame.display.update()
        FPSCLOCK.tick(FPS)

8.运行游戏主入口

编写代码:


if __name__ == '__main__':
    mainGame()

9.经调试后保存最终代码

最终代码展示:

点击查看代码
import pygame  
from pygame.locals import * 
import sys                   
SCREENWIDTH = 822  
SCREENHEIGHT = 199  
FPS = 30 


class MyMap():

    def __init__(self, x, y):
        self.bg = pygame.image.load("image/bg.png").convert_alpha()
        self.x = x
        self.y = y

    def map_rolling(self):
        if self.x < -790: 
            self.x = 800  
        else:
            self.x -= 5  

    def map_update(self):
        SCREEN.blit(self.bg, (self.x, self.y))

# 背景音乐按钮
class Music_Button():
    is_open = True 
    def __init__(self):
        self.open_img = pygame.image.load('image/btn_open.png').convert_alpha()
        self.close_img = pygame.image.load('image/btn_close.png').convert_alpha()
        self.bg_music = pygame.mixer.Sound('audio/bg_music.wav')  
    def is_select(self):
        point_x, point_y = pygame.mouse.get_pos()
        w, h = self.open_img.get_size()            
        in_x = point_x > 20 and point_x < 20 + w
        in_y = point_y > 20 and point_y < 20 + h
        return in_x and in_y





from itertools import cycle 


class Marie():
    def __init__(self):
        self.rect = pygame.Rect(0, 0, 0, 0)
        self.jumpState = False  
        self.jumpHeight = 130  
        self.lowest_y = 140  
        self.jumpValue = 0  
        self.marieIndex = 0
        self.marieIndexGen = cycle([0, 1, 2])
        self.adventure_img = (
            pygame.image.load("image/adventure1.png").convert_alpha(),
            pygame.image.load("image/adventure2.png").convert_alpha(),
            pygame.image.load("image/adventure3.png").convert_alpha(),
        )
        self.jump_audio = pygame.mixer.Sound('audio/jump.wav') 
        self.rect.size = self.adventure_img[0].get_size()
        self.x = 50; 
        self.y = self.lowest_y;  
        self.rect.topleft = (self.x, self.y)

    def jump(self):
        self.jumpState = True

 
    def move(self):
        if self.jumpState:  
            if self.rect.y >= self.lowest_y:  
                self.jumpValue = -5  # 以5个像素值向上移动
            if self.rect.y <= self.lowest_y - self.jumpHeight:  # 小玛丽到达顶部回落
                self.jumpValue = 5  # 以5个像素值向下移动
            self.rect.y += self.jumpValue  # 通过循环改变玛丽的Y坐标
            if self.rect.y >= self.lowest_y:  # 如果小玛丽回到地面
                self.jumpState = False  # 关闭跳跃状态

    # 绘制小玛丽
    def draw_marie(self):
        # 匹配小玛丽动图
        marieIndex = next(self.marieIndexGen)
        # 绘制小玛丽
        SCREEN.blit(self.adventure_img[marieIndex],
                    (self.x, self.rect.y))

import random  # 随机数
# 障碍物类
class Obstacle():
    score = 1  # 分数
    move = 5   # 移动距离
    obstacle_y = 150  # 障碍物y坐标
    def __init__(self):
        # 初始化障碍物矩形
        self.rect = pygame.Rect(0, 0, 0, 0)
        # 加载障碍物图片
        self.missile = pygame.image.load("image/missile.png").convert_alpha()
        self.pipe = pygame.image.load("image/pipe.png").convert_alpha()
        # 加载分数图片
        self.numbers = (pygame.image.load('image/0.png').convert_alpha(),
                        pygame.image.load('image/1.png').convert_alpha(),
                        pygame.image.load('image/2.png').convert_alpha(),
                        pygame.image.load('image/3.png').convert_alpha(),
                        pygame.image.load('image/4.png').convert_alpha(),
                        pygame.image.load('image/5.png').convert_alpha(),
                        pygame.image.load('image/6.png').convert_alpha(),
                        pygame.image.load('image/7.png').convert_alpha(),
                        pygame.image.load('image/8.png').convert_alpha(),
                        pygame.image.load('image/9.png').convert_alpha())
        # 加载加分音效
        self.score_audio = pygame.mixer.Sound('audio/score.wav')  # 加分
        # 0和1随机数
        r = random.randint(0, 1)
        if r == 0:  # 如果随机数为0显示导弹障碍物相反显示管道
            self.image = self.missile   # 显示导弹障碍
            self.move = 15              # 移动速度加快
            self.obstacle_y = 100       # 导弹坐标在天上
        else:
            self.image = self.pipe      # 显示管道障碍
        # 根据障碍物位图的宽高来设置矩形
        self.rect.size = self.image.get_size()
        # 获取位图宽高
        self.width, self.height = self.rect.size
        # 障碍物绘制坐标
        self.x = 800
        self.y = self.obstacle_y
        self.rect.center = (self.x, self.y)

    # 障碍物移动
    def obstacle_move(self):
        self.rect.x -= self.move

    # 绘制障碍物
    def draw_obstacle(self):
        SCREEN.blit(self.image, (self.rect.x, self.rect.y))

    # 获取分数
    def getScore(self):
        self.score
        tmp = self.score;
        if tmp == 1:
            self.score_audio.play()  # 播放加分音乐
        self.score = 0;
        return tmp;

    # 显示分数
    def showScore(self, score):
        # 获取得分数字
        self.scoreDigits = [int(x) for x in list(str(score))]
        totalWidth = 0  # 要显示的所有数字的总宽度
        for digit in self.scoreDigits:
            # 获取积分图片的宽度
            totalWidth += self.numbers[digit].get_width()
        # 分数横向位置
        Xoffset = (SCREENWIDTH - (totalWidth+30))
        for digit in self.scoreDigits:
            # 绘制分数
            SCREEN.blit(self.numbers[digit], (Xoffset, SCREENHEIGHT * 0.1))
            # 随着数字增加改变位置
            Xoffset += self.numbers[digit].get_width()

# 游戏结束的方法
def game_over():
    bump_audio = pygame.mixer.Sound('audio/bump.wav')  # 撞击
    bump_audio.play()  # 播放撞击音效
    # 获取窗体宽、高
    screen_w = pygame.display.Info().current_w
    screen_h = pygame.display.Info().current_h
    # 加载游戏结束的图片
    over_img = pygame.image.load('image/gameover.png').convert_alpha()
    # 将游戏结束的图片绘制在窗体的中间位置
    SCREEN.blit(over_img, ((screen_w - over_img.get_width()) / 2,
                                       (screen_h - over_img.get_height()) / 2))


def mainGame():
    score = 0  # 得分
    over = False  # 游戏结束标记
    global SCREEN, FPSCLOCK
    pygame.init()  # 经过初始化以后我们就可以尽情地使用pygame了。

    # 使用Pygame时钟之前,必须先创建Clock对象的一个实例,
    # 控制每个循环多长时间运行一次。
    FPSCLOCK = pygame.time.Clock()
    SCREEN = pygame.display.set_mode((SCREENWIDTH, SCREENHEIGHT))  # 通常来说我们需要先创建一个窗口,方便我们与程序的交互。
    pygame.display.set_caption('玛丽冒险')  # 设置窗口标题

    # 创建地图对象
    bg1 = MyMap(0, 0)
    bg2 = MyMap(800, 0)

    # 创建小玛丽对象
    marie = Marie()

    addObstacleTimer = 0  # 添加障碍物的时间
    list = []  # 障碍物对象列表

    music_button = Music_Button()     # 创建背景音乐按钮对象
    btn_img  = music_button.open_img  # 设置背景音乐按钮的默认图片
    music_button.bg_music.play(-1)    # 循环播放背景音乐

    while True:
        # 获取单击事件
        for event in pygame.event.get():

            if event.type == pygame.MOUSEBUTTONUP:  # 判断鼠标事件
                if music_button.is_select():        # 判断鼠标是否在静音按钮范围
                    if music_button.is_open:        # 判断背景音乐状态
                        btn_img = music_button.close_img # 单击后显示关闭状态的图片
                        music_button.is_open = False    # 关闭背景音乐状态
                        music_button.bg_music.stop()    # 停止背景音乐的播放
                    else:
                        btn_img = music_button.open_img
                        music_button.is_open = True
                        music_button.bg_music.play(-1)
            # 如果单击了关闭窗口就将窗口关闭
            if event.type == QUIT:
                pygame.quit()  # 退出窗口
                sys.exit()  # 关闭窗口

            # 单击键盘空格键,开启跳的状态
            if event.type == KEYDOWN and event.key == K_SPACE:
                if marie.rect.y >= marie.lowest_y:  # 如果小玛丽在地面上
                    marie.jump_audio.play()  # 播放小玛丽跳跃音效
                    marie.jump()  # 开启小玛丽跳的状态

                if over == True:  # 判断游戏结束的开关是否开启
                    mainGame()  # 如果开启将调用mainGame方法重新启动游戏




        if over == False:
            # 绘制地图起到更新地图的作用
            bg1.map_update()
            # 地图移动
            bg1.map_rolling()
            bg2.map_update()
            bg2.map_rolling()

            # 小玛丽移动
            marie.move()
            # 绘制小玛丽
            marie.draw_marie()

            # 计算障碍物间隔时间
            if addObstacleTimer >= 1300:
                r = random.randint(0, 100)
                if r > 40:
                    # 创建障碍物对象
                    obstacle = Obstacle()
                    # 将障碍物对象添加到列表中
                    list.append(obstacle)
                # 重置添加障碍物时间
                addObstacleTimer = 0

            # 循环遍历障碍物
            for i in range(len(list)):
                # 障碍物移动
                list[i].obstacle_move()
                # 绘制障碍物
                list[i].draw_obstacle()

                # 判断小玛丽与障碍物是否碰撞
                if pygame.sprite.collide_rect(marie, list[i]):
                    over = True  # 碰撞后开启结束开关
                    game_over()  # 调用游戏结束的方法
                    music_button.bg_music.stop()
                else:
                    # 判断小玛丽是否跃过了障碍物
                    if (list[i].rect.x + list[i].rect.width) < marie.rect.x:
                        # 加分
                        score += list[i].getScore()
                # 显示分数
                list[i].showScore(score)

        addObstacleTimer += 20  # 增加障碍物时间
        SCREEN.blit(btn_img, (20, 20)) # 绘制背景音乐按钮
        pygame.display.update()  # 更新整个窗口
        FPSCLOCK.tick(FPS)  # 循环应该多长时间运行一次


if __name__ == '__main__':
    mainGame()

托管到gitee:

8c75029503ced0c2ef8f2c8c526fbcde

托管链接:实验四

(5)运行结果与视频演示

图片运行结果:

image

运行演示视频:

(6)功能总结:

1.背景无限滚动功能
通过两个背景图循环切换、坐标持续左移,实现游戏背景无缝向左滚动,模拟角色向前奔跑的视觉效果。

2.角色跳跃与动画播放功能
按下空格键控制主角玛丽跳跃,实现上升下落的物理效果;循环切换三张角色图片,实现跑步动画,并播放跳跃音效。

3.随机障碍物生成与移动功能
程序定时随机生成管道、导弹两种障碍物,障碍物自动向左移动,导弹障碍物速度更快、位置更高,增加游戏难度。

4.碰撞检测与计分功能
检测主角与障碍物的碰撞,碰撞后触发游戏结束;成功越过障碍物自动加分,实时显示分数并播放加分音效。

5.背景音乐开关与游戏重启功能
点击界面按钮可开启 / 关闭背景音乐;游戏结束后按下空格键可重新启动游戏,同时碰撞时播放撞击音效。

(7)实验中遇到的问题以及解决方法:

1.pygame在我原有的新版本的pycharm中不兼容: 通过下载IDLE(python3.12)进行pygame的下载与实验的完成

2.原有超级玛丽游戏的人物和音乐版权问题: 利用ps软件手绘主角,并在百度搜索可以公开使用的音效与音乐

3.打包成 Windows 独立 exe

(1) 先安装打包工具

打开终端,执行:

pip install pyinstaller

(2) 进入游戏文件夹,执行打包命令

在终端里 cd 到游戏文件夹,输入

pyinstaller -F -w -i game.ico main.py

(3) 得到成品 exe

image

运行结果展示

image

(4) 提供网页下载

创建文本文档,输入代码:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>玛丽冒险 下载</title>
    <style>
        body { text-align: center; margin-top: 100px; font-size: 20px; }
        .download-btn {
            padding: 15px 30px;
            background: #007bff;
            color: white;
            text-decoration: none;
            border-radius: 8px;
            font-size: 20px;
        }
    </style>
</head>
<body>
    <h1>玛丽冒险 - 点击下载游戏</h1>
    <br><br>
    <a href="玛丽冒险.exe" class="download-btn" download>立即下载</a>
</body>
</html>

随后将后缀改为.html,并将其和.exe程序放到同一个文件夹

image

打开网页即提供下载

image

同时提供公开蓝奏云网页下载:20253307张新政实验四
密码:9z3p

image

老师可以自己下载游玩哦(虽然很简陋)

4.在华为云服务器中部署系统

(1) 购买ECS服务器,配置安全组,开放5000端口

购买ECS服务器

image

添加5000端口

0fc43db0bc6f196ead18e10c95413598

(2) 连接服务器,安装部署所需以及上传图像、音乐资源与代码

SSH 远程连接

image

image

安装Python3,pip3,screen,xvfb,pygame,libsdl2,flask

image

d528c9692e4454204c2aa1add2163dc8

image

上传图像、音乐资源与代码

99283ffcd3bdc0247c6d2775958d08a7

(3) 启动游戏网页服务

在命令行中输入python3 marie.py运行程序
浏览器输入 http://1.94.177.52:5000 即可访问

运行结果如下:

290313fed4429f9392281d5a096dd6dd

5.实验感想,全课总结,及课程感想体会、意见和建议

(1) 实验感想:

本次 Python 课程开放实验我选择制作了基于 Pygame 的玛丽冒险小游戏,整体过程充实且充满趣味。Python 拥有丰富的第三方库资源,可供实现游戏开发、数据处理、图形交互等多种功能,前期也让我在众多选题中反复斟酌,最终选择小游戏开发来实践巩固编程知识。不是很难受的是pygame只在老版本的python版本中兼容,而我用的是最新版的导致一直安装不了,几度崩溃,好在最后成功在老版本上安装成功,不过我大意了把原先的pycharm删除,导致最后gitee托管不了,无奈又下载回来,这个过程让我意识到做实验中每一步都要三思而行,如果马马虎虎就进行下一步不仅适得其反,而且可能导致整个实验失败。

(2) 全课总结:

王老师的这门课程让我系统性学习了 Python 的相关知识:从基础语法,函数与类的使用、第三方库调用、文件处理等核心内容,到socket通信、综合性实践。从简单的代码编写到完整项目开发,一步步体会到 Python 语法简洁、拓展性强的优势。同时我也学会了gitee库的建立与将代码托管到gitee上。

Python 简介: 名称 内容
1 语言特点 跨平台、解释型、面向对象、动态类型、高级编程语言
2 地位 TIOBE 排行榜常年Top1
3 开发环境 IDE:编写代码的工具(如 PyCharm、VS Code)。解释器:执行 Python 代码的核心程序,IDE 依赖解释器运行
4 基础语法 注释:# 单行注释;''' ''' / """ """ 多行注释。保留字:Python 自带关键字,不能用作变量名(如 if、for、class)。标识符:变量、函数、类的命名,规则:字母 / 数字 / 下划线,不能以数字开头,区分大小写
5 基本数据类型 整型 (int)、浮点型 (float)、字符串 (str)、布尔型 (bool)
6 运算符 算术:+ - * / // % ** ; 比较:> < >= <= == != ; 赋值:= += -= *= ; 逻辑:and or not

学到的知识点:

一、流程控制语句
1.条件判断:if → elif → else 逐级判断。
2.循环:while:条件满足就循环;for:遍历可迭代对象(列表、字符串等)。

二、序列
1.序列包含的类型:列表[],元组(),字典{key:value},集合{元素}
2.关键区别:list vs tuple:list 可修改,tuple 不可修改。set vs dict:set 存单个元素,dict 存键值对。
3.常用操作:切片,排序

三、字符串
1.常用方法:count():统计子串出现次数。find():查找子串位置,找不到返回 - 1。lower():转小写;upper():转大写。
2.正则表达式:用于匹配、查找、替换复杂字符串规则。

四、函数与面向对象
1.函数:形参:定义时的参数。实参:调用时传入的参数。
2.面向对象三要素:封装、继承、多态。
3.类与对象类:模板(如class Student:)。对象:类的实例(实例化:stu = Student())。
4.核心方法:init():构造方法,创建对象时自动执行,用于初始化属性。
5.概念:封装:隐藏内部实现,只暴露接口。继承:子类继承父类属性与方法,实现代码复用。
6.包与模块:模块:.py 文件,存放代码。包:包含多个模块的文件夹,用于组织代码。

五、异常处理、文件、数据库
1.异常处理:目的:避免程序崩溃,提升健壮性。方式:try-except-else-finally。
2.存储基础:内存:断电丢失、速度快。外存:永久保存、速度慢。
3.冯・诺依曼体系:运算器、控制器、存储器、输入设备、输出设备。
4.数据类型:结构化:有固定格式(数据库表、Excel)。非结构化:无固定格式(图片、音频、文本)。
5.文件操作:核心函数:open() 打开、write() 写入、seek() 移动指针、close() 关闭。
6.数据库(SQLite):优点:轻量、无需安装、内置 Python。
四大操作:增 、删 、改 、查 。

六、爬虫
1.定义:自动抓取网页数据的程序。
2.风险:违规爬取可能违反《网络安全法》《民法典》等,需合法使用。
3.核心两步:爬取:获取网页源码。解析:提取需要的数据。
4.常用库:爬取:requests、urllib。解析:BeautifulSoup、lxml、re(正则)。
5.Robots 协议:robots.txt:网站声明允许 / 禁止爬虫抓取的范围,爬虫应遵守。
6.代理:隐藏真实 IP,防止被目标网站封禁。

(3) 课程感想体会:

志强老师我觉得做的最棒的一点是将理论和实践结合,边讲边给我们敲代码示例,实验课也是一步一步带我们写代码、完善代码再运行,此外志强老师还很幽默,比如盖浇饭和蛋炒饭的形象比喻,很有意思,而且志强老师也很爱笑,笑起来很可爱很治愈,虽然不知道志强老师年龄多大,但是外表和心态都给我一种同龄甚至更活跃积极的感觉。
从刚高考完在小红书上刷到老师的账号,每天期待老师发送校园里的日常,到如今大一下成为王老师的学生,我感到荣幸与感激,很开心上这门课!

image

(4) 意见与建议

意见:不知道其他同学感觉怎么样,反正我是觉得老师讲课的速度有一点点快,每次的实验我都要回到宿舍再通过看网课学习来完成。当然啦,这或许只是我自己理解力差的问题。
建议:觉得老师可以在学习通上每次上课或者是实验课前发一些预习报告,让我们提前学习这节课需要的基础知识,到时候上课再跟着老师写代码我感觉效率会更高,学习效果也会更好。

6.参考文献

(1) pygame入门教程

(2)【Python趣味教学】99%相似度!手把手教你用Python制作超级玛丽游戏

(3) PhotoShop的超实用教程和使用技巧

(4)《python程序设计(第二版)》

posted @ 2026-05-19 09:31  张新政  阅读(57)  评论(3)    收藏  举报
#cnblogs_post_body .video{ height: 0; padding-bottom: 56.25%; /* 16:9 */ position: relative; width: 100%; } #cnblogs_post_body .video iframe{ position: absolute; left: 0; top: 0; width: 100%; height: 100%; }